1 /*
2 * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.opensaml.xml.security.x509;
18
19 import java.security.cert.CRLException;
20 import java.security.cert.CertificateEncodingException;
21 import java.util.List;
22 import java.util.Set;
23
24 import javax.security.auth.x500.X500Principal;
25
26 import org.opensaml.xml.Configuration;
27 import org.opensaml.xml.XMLObject;
28 import org.opensaml.xml.security.SecurityException;
29 import org.opensaml.xml.security.credential.BasicKeyInfoGeneratorFactory;
30 import org.opensaml.xml.security.credential.Credential;
31 import org.opensaml.xml.security.keyinfo.KeyInfoGenerator;
32 import org.opensaml.xml.security.keyinfo.KeyInfoHelper;
33 import org.opensaml.xml.signature.KeyInfo;
34 import org.opensaml.xml.signature.X509CRL;
35 import org.opensaml.xml.signature.X509Certificate;
36 import org.opensaml.xml.signature.X509Data;
37 import org.opensaml.xml.signature.X509SKI;
38 import org.opensaml.xml.signature.impl.KeyInfoBuilder;
39 import org.opensaml.xml.signature.impl.X509DataBuilder;
40 import org.opensaml.xml.util.DatatypeHelper;
41 import org.opensaml.xml.util.LazySet;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 /**
46 * A factory implementation which produces instances of {@link KeyInfoGenerator} capable of
47 * handling the information contained within an {@link X509Credential}.
48 *
49 * All boolean options default to false. The default implementation of {@link X500DNHandler} used is
50 * {@link InternalX500DNHandler}. The default output format for subject and issuer DN's is RFC2253.
51 * The default set of subject alternative names to process is empty.
52 */
53 public class X509KeyInfoGeneratorFactory extends BasicKeyInfoGeneratorFactory {
54
55 /** The set of options configured for the factory. */
56 private X509Options options;
57
58 /** Constructor. */
59 public X509KeyInfoGeneratorFactory() {
60 super();
61 options = (X509Options) super.getOptions();
62 }
63
64 /** {@inheritDoc} */
65 public Class<? extends Credential> getCredentialType() {
66 return X509Credential.class;
67 }
68
69 /** {@inheritDoc} */
70 public boolean handles(Credential credential) {
71 return credential instanceof X509Credential;
72 }
73
74 /** {@inheritDoc} */
75 public KeyInfoGenerator newInstance() {
76 //TODO lock options during cloning ?
77 X509Options newOptions = options.clone();
78 return new X509KeyInfoGenerator(newOptions);
79 }
80
81 /**
82 * Get the option to emit the CRL list as sequence of X509CRL elements within X509Data.
83 *
84 * @return the option value
85 */
86 public boolean emitCRLs() {
87 return options.emitCRLs;
88 }
89
90 /**
91 * Set the option to emit the CRL list as sequence of X509CRL elements within X509Data.
92 *
93 * @param newValue the new option value
94 */
95 public void setEmitCRLs(boolean newValue) {
96 options.emitCRLs = newValue;
97 }
98
99 /**
100 * Get the option to emit the entity certificate as an X509Certificate element within X509Data.
101 *
102 * @return the option value
103 */
104 public boolean emitEntityCertificate() {
105 return options.emitEntityCertificate;
106 }
107
108 /**
109 * Set the option to emit the entity certificate as an X509Certificate element within X509Data.
110 *
111 * @param newValue the new option value
112 */
113 public void setEmitEntityCertificate(boolean newValue) {
114 options.emitEntityCertificate = newValue;
115 }
116
117 /**
118 * Get the option to emit the entity certificate chain as sequence of X509Certificate elements within X509Data.
119 *
120 * @return the option value
121 */
122 public boolean emitEntityCertificateChain() {
123 return options.emitEntityCertificateChain;
124 }
125
126 /**
127 * Set the option to emit the entity certificate chain as sequence of X509Certificate elements within X509Data.
128 *
129 * @param newValue the new option value
130 */
131 public void setEmitEntityCertificateChain(boolean newValue) {
132 options.emitEntityCertificateChain = newValue;
133 }
134
135 /**
136 * Get the option to emit the entity certificate subject alternative name extension values as KeyName elements.
137 *
138 * @return the option value
139 */
140 public boolean emitSubjectAltNamesAsKeyNames() {
141 return options.emitSubjectAltNamesAsKeyNames;
142 }
143
144 /**
145 * Set the option to emit the entity certificate subject alternative name extension values as KeyName elements.
146 *
147 * @param newValue the new option value
148 */
149 public void setEmitSubjectAltNamesAsKeyNames(boolean newValue) {
150 options.emitSubjectAltNamesAsKeyNames = newValue;
151 }
152
153 /**
154 * Get the option to emit the entity certificate subject DN common name (CN) fields as KeyName elements.
155 *
156 * @return the option value
157 */
158 public boolean emitSubjectCNAsKeyName() {
159 return options.emitSubjectCNAsKeyName;
160 }
161
162 /**
163 * Set the option to emit the entity certificate subject DN common name (CN) fields as KeyName elements.
164 *
165 * @param newValue the new option value
166 */
167 public void setEmitSubjectCNAsKeyName(boolean newValue) {
168 options.emitSubjectCNAsKeyName = newValue;
169 }
170
171 /**
172 * Get the option to emit the entity certificate subject DN as a KeyName element.
173 *
174 * @return the option value
175 */
176 public boolean emitSubjectDNAsKeyName() {
177 return options.emitSubjectDNAsKeyName;
178 }
179
180 /**
181 * Set the option to emit the entity certificate subject DN as a KeyName element.
182 *
183 * @param newValue the new option value
184 */
185 public void setEmitSubjectDNAsKeyName(boolean newValue) {
186 options.emitSubjectDNAsKeyName = newValue;
187 }
188
189 /**
190 * Get the option to emit the entity certificate issuer name and serial number as
191 * an X509IssuerSerial element within X509Data.
192 *
193 * @return the option value
194 */
195 public boolean emitX509IssuerSerial() {
196 return options.emitX509IssuerSerial;
197 }
198
199 /**
200 * Set the option to emit the entity certificate issuer name and serial number as
201 * an X509IssuerSerial element within X509Data.
202 *
203 * @param newValue the new option value
204 */
205 public void setEmitX509IssuerSerial(boolean newValue) {
206 options.emitX509IssuerSerial = newValue;
207 }
208
209 /**
210 * Get the option to emit the entity certificate subject key identifier as an X509SKI element within X509Data.
211 *
212 * @return the option value
213 */
214 public boolean emitX509SKI() {
215 return options.emitX509SKI;
216 }
217
218 /**
219 * Set the option to emit the entity certificate subject key identifier as an X509SKI element within X509Data.
220 *
221 * @param newValue the new option value
222 */
223 public void setEmitX509SKI(boolean newValue) {
224 options.emitX509SKI = newValue;
225 }
226
227 /**
228 * Get the option to emit the entity certificate subject DN as an X509SubjectName element within X509Data.
229 *
230 * @return the option value
231 */
232 public boolean emitX509SubjectName() {
233 return options.emitX509SubjectName;
234 }
235
236 /**
237 * Set the option to emit the entity certificate subject DN as an X509SubjectName element within X509Data.
238 *
239 * @param newValue the new option value
240 */
241 public void setEmitX509SubjectName(boolean newValue) {
242 options.emitX509SubjectName = newValue;
243 }
244
245 /**
246 * The set of types of subject alternative names to process.
247 *
248 * Name types are represented using the constant OID tag name values defined
249 * in {@link X509Util}.
250 *
251 *
252 * @return the modifiable set of alt name identifiers
253 */
254 public Set<Integer> getSubjectAltNames() {
255 return options.subjectAltNames;
256 }
257
258 /**
259 * Get the handler which process X.500 distinguished names.
260 *
261 * Defaults to {@link InternalX500DNHandler}.
262 *
263 * @return returns the X500DNHandler instance
264 */
265 public X500DNHandler getX500DNHandler() {
266 return options.x500DNHandler;
267 }
268
269 /**
270 * Set the handler which process X.500 distinguished names.
271 *
272 * Defaults to {@link InternalX500DNHandler}.
273 *
274 * @param handler the new X500DNHandler instance
275 */
276 public void setX500DNHandler(X500DNHandler handler) {
277 if (handler == null) {
278 throw new IllegalArgumentException("X500DNHandler may not be null");
279 }
280 options.x500DNHandler = handler;
281 }
282
283 /**
284 * Get the output format specifier for X.500 subject names.
285 *
286 * Defaults to RFC2253 format. The meaning of this format specifier value
287 * is dependent upon the implementation of {@link X500DNHandler} which is used.
288 *
289 * @return returns the format specifier
290 */
291 public String getX500SubjectDNFormat() {
292 return options.x500SubjectDNFormat;
293 }
294
295 /**
296 * Set the output format specifier for X.500 subject names.
297 *
298 * Defaults to RFC2253 format. The meaning of this format specifier value
299 * is dependent upon the implementation of {@link X500DNHandler} which is used.
300 *
301 * @param format the new X500DNHandler instance
302 */
303 public void setX500SubjectDNFormat(String format) {
304 options.x500SubjectDNFormat = format;
305 }
306
307 /**
308 * Get the output format specifier for X.500 issuer names.
309 *
310 * Defaults to RFC2253 format. The meaning of this format specifier value
311 * is dependent upon the implementation of {@link X500DNHandler} which is used.
312 *
313 * @return returns the format specifier
314 */
315 public String getX500IssuerDNFormat() {
316 return options.x500IssuerDNFormat;
317 }
318
319 /**
320 * Set the output format specifier for X.500 issuer names.
321 *
322 * Defaults to RFC2253 format. The meaning of this format specifier value
323 * is dependent upon the implementation of {@link X500DNHandler} which is used.
324 *
325 * @param format the new X500DNHandler instance
326 */
327 public void setX500IssuerDNFormat(String format) {
328 options.x500IssuerDNFormat = format;
329 }
330
331 /** {@inheritDoc} */
332 protected X509Options getOptions() {
333 return options;
334 }
335
336 /** {@inheritDoc} */
337 protected X509Options newOptions() {
338 return new X509Options();
339 }
340
341 /**
342 * An implementation of {@link KeyInfoGenerator} capable of handling the information
343 * contained within a {@link X509Credential}.
344 */
345 public class X509KeyInfoGenerator extends BasicKeyInfoGenerator {
346
347 /** Class logger. */
348 private final Logger log = LoggerFactory.getLogger(X509KeyInfoGenerator.class);
349
350 /** The set of options to be used by the generator.*/
351 private X509Options options;
352
353 /** Builder for KeyInfo objects. */
354 private KeyInfoBuilder keyInfoBuilder;
355
356 /** Builder for X509Data objects. */
357 private X509DataBuilder x509DataBuilder;
358
359 /**
360 * Constructor.
361 *
362 * @param newOptions the options to be used by the generator
363 */
364 protected X509KeyInfoGenerator(X509Options newOptions) {
365 super(newOptions);
366 options = newOptions;
367
368 keyInfoBuilder =
369 (KeyInfoBuilder) Configuration.getBuilderFactory().getBuilder(KeyInfo.DEFAULT_ELEMENT_NAME);
370 x509DataBuilder =
371 (X509DataBuilder) Configuration.getBuilderFactory().getBuilder(X509Data.DEFAULT_ELEMENT_NAME);
372 }
373
374 /** {@inheritDoc} */
375 public KeyInfo generate(Credential credential) throws SecurityException {
376 if ( ! (credential instanceof X509Credential) ) {
377 log.warn("X509KeyInfoGenerator was passed a credential that was not an instance of X509Credential: {}",
378 credential.getClass().getName());
379 return null;
380 }
381 X509Credential x509Credential = (X509Credential) credential;
382
383 KeyInfo keyInfo = super.generate(credential);
384 if (keyInfo == null) {
385 keyInfo = keyInfoBuilder.buildObject();
386 }
387 X509Data x509Data = x509DataBuilder.buildObject();
388
389 processEntityCertificate(keyInfo, x509Data, x509Credential);
390 processEntityCertificateChain(keyInfo, x509Data, x509Credential);
391 processCRLs(keyInfo, x509Data, x509Credential);
392
393 List<XMLObject> x509DataChildren = x509Data.getOrderedChildren();
394 if (x509DataChildren != null && x509DataChildren.size() > 0) {
395 keyInfo.getX509Datas().add(x509Data);
396 }
397
398 List<XMLObject> keyInfoChildren = keyInfo.getOrderedChildren();
399 if (keyInfoChildren != null && keyInfoChildren.size() > 0) {
400 return keyInfo;
401 } else {
402 return null;
403 }
404 }
405
406 /** Process the value of {@link X509Credential#getEntityCertificate()}.
407 *
408 * @param keyInfo the KeyInfo that is being built
409 * @param x509Data the X509Data that is being built
410 * @param credential the Credential that is being processed
411 * @throws SecurityException thrown if the certificate data can not be encoded from the Java certificate object
412 */
413 protected void processEntityCertificate(KeyInfo keyInfo, X509Data x509Data, X509Credential credential)
414 throws SecurityException {
415
416 if (credential.getEntityCertificate() == null) {
417 return;
418 }
419
420 java.security.cert.X509Certificate javaCert = credential.getEntityCertificate();
421
422 processCertX509DataOptions(x509Data, javaCert);
423 processCertKeyNameOptions(keyInfo, javaCert);
424
425 // The cert chain includes the entity cert, so don't add a duplicate
426 if (options.emitEntityCertificate && ! options.emitEntityCertificateChain) {
427 try {
428 X509Certificate xmlCert = KeyInfoHelper.buildX509Certificate(javaCert);
429 x509Data.getX509Certificates().add(xmlCert);
430 } catch (CertificateEncodingException e) {
431 throw new SecurityException("Error generating X509Certificate element "
432 + "from credential's end-entity certificate", e);
433 }
434 }
435
436 }
437
438 /**
439 * Process the options related to generation of child elements of X509Data based on certificate data.
440 *
441 * @param x509Data the X509Data element being processed.
442 * @param cert the certificate being processed
443 */
444 protected void processCertX509DataOptions(X509Data x509Data, java.security.cert.X509Certificate cert) {
445 processCertX509SubjectName(x509Data, cert);
446 processCertX509IssuerSerial(x509Data, cert);
447 processCertX509SKI(x509Data, cert);
448 }
449
450 /**
451 * Process the options related to generation of KeyName elements based on certificate data.
452 *
453 * @param keyInfo the KeyInfo element being processed.
454 * @param cert the certificate being processed
455 */
456 protected void processCertKeyNameOptions(KeyInfo keyInfo, java.security.cert.X509Certificate cert) {
457 processSubjectDNKeyName(keyInfo, cert);
458 processSubjectCNKeyName(keyInfo, cert);
459 processSubjectAltNameKeyNames(keyInfo, cert);
460 }
461
462 /**
463 * Process the options related to generation of the X509SubjectDN child element of X509Data
464 * based on certificate data.
465 *
466 * @param x509Data the X509Data element being processed.
467 * @param cert the certificate being processed
468 */
469 protected void processCertX509SubjectName(X509Data x509Data, java.security.cert.X509Certificate cert) {
470 if (options.emitX509SubjectName) {
471 String subjectNameValue = getSubjectName(cert);
472 if (! DatatypeHelper.isEmpty(subjectNameValue)) {
473 x509Data.getX509SubjectNames().add( KeyInfoHelper.buildX509SubjectName(subjectNameValue));
474 }
475 }
476 }
477
478 /**
479 * Process the options related to generation of the X509IssuerSerial child element of X509Data
480 * based on certificate data.
481 *
482 * @param x509Data the X509Data element being processed.
483 * @param cert the certificate being processed
484 */
485 protected void processCertX509IssuerSerial(X509Data x509Data, java.security.cert.X509Certificate cert) {
486 if (options.emitX509IssuerSerial) {
487 String issuerNameValue = getIssuerName(cert);
488 if (! DatatypeHelper.isEmpty(issuerNameValue)) {
489 x509Data.getX509IssuerSerials().add(
490 KeyInfoHelper.buildX509IssuerSerial(issuerNameValue, cert.getSerialNumber()) );
491 }
492 }
493 }
494
495 /**
496 * Process the options related to generation of the X509SKI child element of X509Data
497 * based on certificate data.
498 *
499 * @param x509Data the X509Data element being processed.
500 * @param cert the certificate being processed
501 */
502 protected void processCertX509SKI(X509Data x509Data, java.security.cert.X509Certificate cert) {
503 if (options.emitX509SKI) {
504 X509SKI xmlSKI = KeyInfoHelper.buildX509SKI(cert);
505 if (xmlSKI != null) {
506 x509Data.getX509SKIs().add(xmlSKI);
507 }
508 }
509 }
510
511 /**
512 * Get subject name from a certificate, using the currently configured X500DNHandler
513 * and subject DN output format.
514 *
515 * @param cert the certificate being processed
516 * @return the subject name
517 */
518 protected String getSubjectName(java.security.cert.X509Certificate cert) {
519 if (cert == null) {
520 return null;
521 }
522 if (! DatatypeHelper.isEmpty(options.x500SubjectDNFormat)) {
523 return options.x500DNHandler.getName(cert.getSubjectX500Principal(), options.x500SubjectDNFormat);
524 } else {
525 return options.x500DNHandler.getName(cert.getSubjectX500Principal());
526 }
527 }
528
529 /**
530 * Get issuer name from a certificate, using the currently configured X500DNHandler
531 * and issuer DN output format.
532 *
533 * @param cert the certificate being processed
534 * @return the issuer name
535 */
536 protected String getIssuerName(java.security.cert.X509Certificate cert) {
537 if (cert == null) {
538 return null;
539 }
540 if (! DatatypeHelper.isEmpty(options.x500IssuerDNFormat)) {
541 return options.x500DNHandler.getName(cert.getIssuerX500Principal(), options.x500IssuerDNFormat);
542 } else {
543 return options.x500DNHandler.getName(cert.getIssuerX500Principal());
544 }
545 }
546
547 /**
548 * Process the options related to generation of KeyName elements based on the certificate's
549 * subject DN value.
550 *
551 * @param keyInfo the KeyInfo element being processed.
552 * @param cert the certificate being processed
553 */
554 protected void processSubjectDNKeyName(KeyInfo keyInfo, java.security.cert.X509Certificate cert) {
555 if (options.emitSubjectDNAsKeyName) {
556 String subjectNameValue = getSubjectName(cert);
557 if (! DatatypeHelper.isEmpty(subjectNameValue)) {
558 KeyInfoHelper.addKeyName(keyInfo, subjectNameValue);
559 }
560 }
561 }
562
563 /**
564 * Process the options related to generation of KeyName elements based on the
565 * the common name field(s) of the certificate's subject DN.
566 *
567 * @param keyInfo the KeyInfo element being processed.
568 * @param cert the certificate being processed
569 */
570 protected void processSubjectCNKeyName(KeyInfo keyInfo, java.security.cert.X509Certificate cert) {
571 if (options.emitSubjectCNAsKeyName) {
572 for (String name : X509Util.getCommonNames(cert.getSubjectX500Principal())) {
573 if (! DatatypeHelper.isEmpty(name)) {
574 KeyInfoHelper.addKeyName(keyInfo, name);
575 }
576 }
577 }
578 }
579
580 /**
581 * Process the options related to generation of KeyName elements based on subject
582 * alternative name information within the certificate data.
583 *
584 * @param keyInfo the KeyInfo element being processed.
585 * @param cert the certificate being processed
586 */
587 protected void processSubjectAltNameKeyNames(KeyInfo keyInfo, java.security.cert.X509Certificate cert) {
588 if (options.emitSubjectAltNamesAsKeyNames && options.subjectAltNames.size() > 0) {
589 Integer[] nameTypes = new Integer[ options.subjectAltNames.size() ];
590 options.subjectAltNames.toArray(nameTypes);
591 for (Object altNameValue : X509Util.getAltNames(cert, nameTypes)) {
592 // Each returned value should either be a String or a DER-encoded byte array.
593 // See X509Certificate#getSubjectAlternativeNames for the type rules.
594 if (altNameValue instanceof String) {
595 KeyInfoHelper.addKeyName(keyInfo, (String) altNameValue);
596 } else if (altNameValue instanceof byte[]){
597 log.warn("Certificate contained an alt name value as a DER-encoded byte[] (not supported)");
598 } else {
599 log.warn("Certificate contained an alt name value with an unexpected type: {}",
600 altNameValue.getClass().getName());
601 }
602 }
603 }
604 }
605
606 /** Process the value of {@link X509Credential#getEntityCertificateChain()}.
607 *
608 * @param keyInfo the KeyInfo that is being built
609 * @param x509Data the X509Data that is being built
610 * @param credential the Credential that is being processed
611 * @throws SecurityException thrown if the certificate data can not be encoded from the Java certificate object
612 */
613 protected void processEntityCertificateChain(KeyInfo keyInfo, X509Data x509Data, X509Credential credential)
614 throws SecurityException {
615
616 if (options.emitEntityCertificateChain && credential.getEntityCertificateChain() != null) {
617 for (java.security.cert.X509Certificate javaCert : credential.getEntityCertificateChain()) {
618 try {
619 X509Certificate xmlCert = KeyInfoHelper.buildX509Certificate(javaCert);
620 x509Data.getX509Certificates().add(xmlCert);
621 } catch (CertificateEncodingException e) {
622 throw new SecurityException("Error generating X509Certificate element "
623 + "from a certificate in credential's certificate chain", e);
624 }
625 }
626 }
627 }
628
629 /** Process the value of {@link X509Credential#getCRLs()}.
630 *
631 * @param keyInfo the KeyInfo that is being built
632 * @param x509Data the X509Data that is being built
633 * @param credential the Credential that is being processed
634 * @throws SecurityException thrown if the CRL data can not be encoded from the Java certificate object
635 */
636 protected void processCRLs(KeyInfo keyInfo, X509Data x509Data, X509Credential credential)
637 throws SecurityException {
638
639 if (options.emitCRLs && credential.getCRLs() != null) {
640 for (java.security.cert.X509CRL javaCRL : credential.getCRLs()) {
641 try {
642 X509CRL xmlCRL = KeyInfoHelper.buildX509CRL(javaCRL);
643 x509Data.getX509CRLs().add(xmlCRL);
644 } catch (CRLException e) {
645 throw new SecurityException("Error generating X509CRL element "
646 + "from a CRL in credential's CRL list", e);
647 }
648 }
649 }
650 }
651
652 }
653
654 /**
655 * Options to be used in the production of a {@link KeyInfo} from an {@link X509Credential}.
656 */
657 protected class X509Options extends BasicOptions {
658
659 /** Emit the entity certificate as an X509Certificate element within X509Data. */
660 private boolean emitEntityCertificate;
661
662 /** Emit the entity certificate chain as sequence of X509Certificate elements within X509Data. */
663 private boolean emitEntityCertificateChain;
664
665 /** Emit the CRL list as sequence of X509CRL elements within X509Data. */
666 private boolean emitCRLs;
667
668 /** Emit the entity certificate subject DN as an X509SubjectName element within X509Data. */
669 private boolean emitX509SubjectName;
670
671 /** Emit the entity certificate issuer name and serial number as an X509IssuerSerial element within X509Data. */
672 private boolean emitX509IssuerSerial;
673
674 /** Emit the entity certificate subject key identifier as an X509SKI element within X509Data. */
675 private boolean emitX509SKI;
676
677 /** Emit the entity certificate subject DN as a KeyName element. */
678 private boolean emitSubjectDNAsKeyName;
679
680 /** Emit the entity certificate subject DN common name (CN) fields as KeyName elements. */
681 private boolean emitSubjectCNAsKeyName;
682
683 /** Emit the entity certificate subject alternative name extension values as KeyName elements. */
684 private boolean emitSubjectAltNamesAsKeyNames;
685
686 /** The set of types of subject alternative names to process. */
687 private Set<Integer> subjectAltNames;
688
689 /** Responsible for parsing and serializing X.500 names to/from {@link X500Principal} instances. */
690 private X500DNHandler x500DNHandler;
691
692 /** The format specifier for outputting X.500 subject names. */
693 private String x500SubjectDNFormat;
694
695 /** The format specifier for outputting X.500 issuer names. */
696 private String x500IssuerDNFormat;
697
698 /** Constructor. */
699 protected X509Options() {
700 subjectAltNames = new LazySet<Integer>();
701 x500DNHandler = new InternalX500DNHandler();
702 x500SubjectDNFormat = X500DNHandler.FORMAT_RFC2253;
703 x500IssuerDNFormat = X500DNHandler.FORMAT_RFC2253;
704 }
705
706 /** {@inheritDoc} */
707 protected X509Options clone() {
708 X509Options clonedOptions = (X509Options) super.clone();
709
710 clonedOptions.subjectAltNames = new LazySet<Integer>();
711 clonedOptions.subjectAltNames.addAll(this.subjectAltNames);
712
713 clonedOptions.x500DNHandler = this.x500DNHandler.clone();
714
715 return clonedOptions;
716 }
717
718 }
719
720 }