1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.message;
21
22 import java.security.NoSuchProviderException;
23 import java.security.Provider;
24 import java.security.PublicKey;
25 import java.security.cert.CertificateEncodingException;
26 import java.security.cert.X509Certificate;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30
31 import javax.xml.crypto.XMLStructure;
32 import javax.xml.crypto.dom.DOMStructure;
33 import javax.xml.crypto.dsig.CanonicalizationMethod;
34 import javax.xml.crypto.dsig.SignatureMethod;
35 import javax.xml.crypto.dsig.SignedInfo;
36 import javax.xml.crypto.dsig.XMLSignContext;
37 import javax.xml.crypto.dsig.XMLSignature;
38 import javax.xml.crypto.dsig.XMLSignatureFactory;
39 import javax.xml.crypto.dsig.dom.DOMSignContext;
40 import javax.xml.crypto.dsig.keyinfo.KeyInfo;
41 import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
42 import javax.xml.crypto.dsig.keyinfo.KeyValue;
43 import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
44 import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
45
46 import org.apache.wss4j.common.WSEncryptionPart;
47 import org.apache.wss4j.common.WSS4JConstants;
48 import org.apache.wss4j.common.crypto.Crypto;
49 import org.apache.wss4j.common.crypto.CryptoType;
50 import org.apache.wss4j.common.crypto.DERDecoder;
51 import org.apache.wss4j.common.ext.WSSecurityException;
52 import org.apache.wss4j.common.token.BinarySecurity;
53 import org.apache.wss4j.common.token.DOMX509Data;
54 import org.apache.wss4j.common.token.DOMX509IssuerSerial;
55 import org.apache.wss4j.common.token.PKIPathSecurity;
56 import org.apache.wss4j.common.token.Reference;
57 import org.apache.wss4j.common.token.SecurityTokenReference;
58 import org.apache.wss4j.common.token.X509Security;
59 import org.apache.wss4j.common.util.AttachmentUtils;
60 import org.apache.wss4j.common.util.KeyUtils;
61 import org.apache.wss4j.common.util.XMLUtils;
62 import org.apache.wss4j.dom.WSConstants;
63 import org.apache.wss4j.dom.WSDocInfo;
64 import org.apache.wss4j.dom.message.token.KerberosSecurity;
65 import org.apache.wss4j.dom.transform.STRTransform;
66 import org.apache.wss4j.dom.util.WSSecurityUtil;
67 import org.w3c.dom.Document;
68 import org.w3c.dom.Element;
69 import org.w3c.dom.Node;
70
71
72
73
74
75
76
77
78
79
80
81
82 public class WSSecSignature extends WSSecSignatureBase {
83
84 private static final org.slf4j.Logger LOG =
85 org.slf4j.LoggerFactory.getLogger(WSSecSignature.class);
86
87 protected XMLSignatureFactory signatureFactory;
88 protected KeyInfo keyInfo;
89 protected CanonicalizationMethod c14nMethod;
90 protected XMLSignature sig;
91 protected byte[] secretKey;
92 protected String strUri;
93 protected Element bstToken;
94 protected String keyInfoUri;
95 protected String certUri;
96 protected byte[] signatureValue;
97
98 private boolean useSingleCert = true;
99 private String sigAlgo;
100 private String canonAlgo = WSConstants.C14N_EXCL_OMIT_COMMENTS;
101 private SecurityTokenReference secRef;
102 private String customTokenValueType;
103 private String customTokenId;
104 private String encrKeySha1value;
105 private Crypto crypto;
106 private String digestAlgo = WSConstants.SHA1;
107 private X509Certificate useThisCert;
108 private boolean useCustomSecRef;
109 private boolean bstAddedToSecurityHeader;
110 private boolean includeSignatureToken;
111 private boolean addInclusivePrefixes = true;
112 private Element customKeyInfoElement;
113 private Provider signatureProvider;
114
115 public WSSecSignature(WSSecHeader securityHeader) {
116 this(securityHeader, null);
117 }
118
119 public WSSecSignature(WSSecHeader securityHeader, Provider provider) {
120 super(securityHeader);
121 init(provider);
122 }
123
124 public WSSecSignature(Document doc) {
125 this(doc, null);
126 }
127
128 public WSSecSignature(Document doc, Provider provider) {
129 super(doc);
130 init(provider);
131 }
132
133 private void init(Provider provider) {
134 if (provider == null) {
135
136
137 try {
138 signatureFactory = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
139 } catch (NoSuchProviderException ex) {
140 signatureFactory = XMLSignatureFactory.getInstance("DOM");
141 }
142 } else {
143 signatureFactory = XMLSignatureFactory.getInstance("DOM", provider);
144 }
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 public void prepare(Crypto cr)
161 throws WSSecurityException {
162
163
164
165
166 crypto = cr;
167 WSDocInfo wsDocInfo = getWsDocInfo();
168 if (wsDocInfo == null) {
169 wsDocInfo = new WSDocInfo(getDocument());
170 super.setWsDocInfo(wsDocInfo);
171 }
172 wsDocInfo.setCrypto(cr);
173
174
175
176
177 X509Certificate[] certs = getSigningCerts();
178
179 try {
180 C14NMethodParameterSpec c14nSpec = null;
181 if (addInclusivePrefixes && canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
182 Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
183 List<String> prefixes =
184 getInclusivePrefixes(securityHeaderElement, false);
185 c14nSpec = new ExcC14NParameterSpec(prefixes);
186 }
187
188 c14nMethod = signatureFactory.newCanonicalizationMethod(canonAlgo, c14nSpec);
189 } catch (Exception ex) {
190 LOG.error("", ex);
191 throw new WSSecurityException(
192 WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex, "noXMLSig"
193 );
194 }
195
196 keyInfoUri = getIdAllocator().createSecureId("KI-", keyInfo);
197 if (!useCustomSecRef && customKeyInfoElement == null) {
198 secRef = new SecurityTokenReference(getDocument());
199 strUri = getIdAllocator().createSecureId("STR-", secRef);
200 secRef.addWSSENamespace();
201 secRef.addWSUNamespace();
202 secRef.setID(strUri);
203
204
205
206
207
208
209
210
211 switch (keyIdentifierType) {
212 case WSConstants.BST_DIRECT_REFERENCE:
213 Reference ref = new Reference(getDocument());
214 ref.setURI("#" + certUri);
215
216 addBST(certs);
217 if (!useSingleCert) {
218 secRef.addTokenType(PKIPathSecurity.PKI_TYPE);
219 ref.setValueType(PKIPathSecurity.PKI_TYPE);
220 } else {
221 ref.setValueType(X509Security.X509_V3_TYPE);
222 }
223 secRef.setReference(ref);
224 break;
225
226 case WSConstants.ISSUER_SERIAL:
227 addIssuerSerial(certs,false);
228 break;
229
230 case WSConstants.ISSUER_SERIAL_QUOTE_FORMAT:
231 addIssuerSerial(certs,true);
232 break;
233
234 case WSConstants.X509_KEY_IDENTIFIER:
235 secRef.setKeyIdentifier(certs[0]);
236 break;
237
238 case WSConstants.SKI_KEY_IDENTIFIER:
239 secRef.setKeyIdentifierSKI(certs[0], crypto);
240
241 if (includeSignatureToken) {
242 addBST(certs);
243 }
244 break;
245
246 case WSConstants.THUMBPRINT_IDENTIFIER:
247 secRef.setKeyIdentifierThumb(certs[0]);
248
249 if (includeSignatureToken) {
250 addBST(certs);
251 }
252 break;
253
254 case WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER:
255 if (encrKeySha1value != null) {
256 secRef.setKeyIdentifierEncKeySHA1(encrKeySha1value);
257 } else {
258 byte[] digestBytes = KeyUtils.generateDigest(secretKey);
259 secRef.setKeyIdentifierEncKeySHA1(org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes));
260 }
261 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
262 break;
263
264 case WSConstants.CUSTOM_SYMM_SIGNING :
265 Reference refCust = new Reference(getDocument());
266 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customTokenValueType)) {
267 secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
268 refCust.setValueType(customTokenValueType);
269 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customTokenValueType)) {
270 secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
271 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customTokenValueType)) {
272 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
273 refCust.setValueType(customTokenValueType);
274 } else if (KerberosSecurity.isKerberosToken(customTokenValueType)) {
275 secRef.addTokenType(customTokenValueType);
276 refCust.setValueType(customTokenValueType);
277 } else {
278 refCust.setValueType(customTokenValueType);
279 }
280 refCust.setURI("#" + customTokenId);
281 secRef.setReference(refCust);
282 break;
283
284 case WSConstants.CUSTOM_SYMM_SIGNING_DIRECT :
285 Reference refCustd = new Reference(getDocument());
286 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customTokenValueType)) {
287 secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
288 refCustd.setValueType(customTokenValueType);
289 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customTokenValueType)) {
290 secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
291 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customTokenValueType)) {
292 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
293 refCustd.setValueType(customTokenValueType);
294 } else if (KerberosSecurity.isKerberosToken(customTokenValueType)) {
295 secRef.addTokenType(customTokenValueType);
296 refCustd.setValueType(customTokenValueType);
297 } else {
298 refCustd.setValueType(customTokenValueType);
299 }
300 refCustd.setURI(customTokenId);
301 secRef.setReference(refCustd);
302 break;
303
304 case WSConstants.CUSTOM_KEY_IDENTIFIER:
305 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customTokenValueType)) {
306 secRef.setKeyIdentifier(customTokenValueType, customTokenId);
307 secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
308 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customTokenValueType)) {
309 secRef.setKeyIdentifier(customTokenValueType, customTokenId);
310 secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
311 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customTokenValueType)) {
312 secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
313 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
314 } else if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(customTokenValueType)) {
315 secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
316 secRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
317 } else if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(customTokenValueType)) {
318 secRef.setKeyIdentifier(customTokenValueType, customTokenId, true);
319 secRef.addTokenType(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
320 }
321 break;
322
323 case WSConstants.KEY_VALUE:
324 java.security.PublicKey publicKey = certs[0].getPublicKey();
325
326 try {
327 KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
328 KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);
329 keyInfo =
330 keyInfoFactory.newKeyInfo(Collections.singletonList(keyValue), keyInfoUri);
331 } catch (java.security.KeyException ex) {
332 LOG.error("", ex);
333 throw new WSSecurityException(
334 WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex, "noXMLSig"
335 );
336 }
337 break;
338 default:
339 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId");
340 }
341 }
342
343 if (keyIdentifierType != WSConstants.KEY_VALUE) {
344 marshalKeyInfo(wsDocInfo);
345 }
346 }
347
348 private void addIssuerSerial(X509Certificate[] certs,boolean isCommaDelimited) throws WSSecurityException {
349 String issuer = certs[0].getIssuerX500Principal().getName();
350 java.math.BigInteger serialNumber = certs[0].getSerialNumber();
351
352 DOMX509IssuerSerial domIssuerSerial
353 = new DOMX509IssuerSerial(getDocument(), issuer, serialNumber, isCommaDelimited);
354 DOMX509Data domX509Data = new DOMX509Data(getDocument(), domIssuerSerial);
355 secRef.setUnknownElement(domX509Data.getElement());
356
357 if (includeSignatureToken) {
358 addBST(certs);
359 }
360 }
361
362 protected void marshalKeyInfo(WSDocInfo wsDocInfo) throws WSSecurityException {
363 List<XMLStructure> kiChildren = null;
364 if (customKeyInfoElement == null) {
365 XMLStructure structure = new DOMStructure(secRef.getElement());
366 wsDocInfo.addTokenElement(secRef.getElement(), false);
367 kiChildren = Collections.singletonList(structure);
368 } else {
369 Node kiChild = customKeyInfoElement.getFirstChild();
370 kiChildren = new ArrayList<>();
371 while (kiChild != null) {
372 kiChildren.add(new DOMStructure(kiChild));
373 kiChild = kiChild.getNextSibling();
374 }
375 }
376
377 KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
378 keyInfo = keyInfoFactory.newKeyInfo(kiChildren, keyInfoUri);
379 }
380
381
382
383
384
385
386
387
388
389
390
391
392 public Document build(Crypto cr)
393 throws WSSecurityException {
394
395 LOG.debug("Beginning signing...");
396
397 prepare(cr);
398 if (getParts().isEmpty()) {
399 getParts().add(WSSecurityUtil.getDefaultEncryptionPart(getDocument()));
400 } else {
401 for (WSEncryptionPart part : getParts()) {
402 if (part.getId() == null && "STRTransform".equals(part.getName())) {
403 part.setId(strUri);
404 } else if ("KeyInfo".equals(part.getName()) && WSConstants.SIG_NS.equals(part.getNamespace())
405 && part.getElement() == null) {
406
407 part.setId(keyInfoUri);
408 }
409 }
410 }
411
412 List<javax.xml.crypto.dsig.Reference> referenceList = addReferencesToSign(getParts());
413
414 computeSignature(referenceList);
415
416
417
418
419
420 if (bstToken != null) {
421 prependBSTElementToHeader();
422 }
423
424 return getDocument();
425 }
426
427
428
429
430
431
432
433
434 public List<javax.xml.crypto.dsig.Reference> addReferencesToSign(
435 List<WSEncryptionPart> references
436 ) throws WSSecurityException {
437 return
438 addReferencesToSign(
439 getDocument(),
440 references,
441 getWsDocInfo(),
442 signatureFactory,
443 addInclusivePrefixes,
444 digestAlgo
445 );
446 }
447
448
449
450
451
452
453 public Element getSignatureElement() {
454 Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
455 return
456 XMLUtils.getDirectChildElement(
457 securityHeaderElement, WSConstants.SIG_LN, WSConstants.SIG_NS
458 );
459 }
460
461
462
463
464 private void addBST(X509Certificate[] certs) throws WSSecurityException {
465 if (storeBytesInAttachment) {
466 bstToken =
467 getDocument().createElementNS(WSS4JConstants.WSSE_NS, "wsse:BinarySecurityToken");
468 bstToken.setAttributeNS(null, "EncodingType", WSS4JConstants.BASE64_ENCODING);
469 bstToken.setAttributeNS(WSS4JConstants.WSU_NS, WSS4JConstants.WSU_PREFIX + ":Id", certUri);
470 if (addWSUNamespace) {
471 bstToken.setAttributeNS(XMLUtils.XMLNS_NS, "xmlns:" + WSConstants.WSU_PREFIX, WSConstants.WSU_NS);
472 }
473
474 byte[] certBytes = null;
475 if (!useSingleCert) {
476 bstToken.setAttributeNS(null, "ValueType", PKIPathSecurity.PKI_TYPE);
477 certBytes = crypto.getBytesFromCertificates(certs);
478 } else {
479 bstToken.setAttributeNS(null, "ValueType", X509Security.X509_V3_TYPE);
480 try {
481 certBytes = certs[0].getEncoded();
482 } catch (CertificateEncodingException e) {
483 throw new WSSecurityException(
484 WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "encodeError"
485 );
486 }
487 }
488
489 final String attachmentId = getIdAllocator().createId("", getDocument());
490 AttachmentUtils.storeBytesInAttachment(bstToken, getDocument(), attachmentId,
491 certBytes, attachmentCallbackHandler);
492 getWsDocInfo().addTokenElement(bstToken, false);
493 } else {
494 BinarySecurity binarySecurity = null;
495 if (!useSingleCert) {
496 binarySecurity = new PKIPathSecurity(getDocument());
497 ((PKIPathSecurity) binarySecurity).setX509Certificates(certs, crypto);
498 } else {
499 binarySecurity = new X509Security(getDocument());
500 ((X509Security) binarySecurity).setX509Certificate(certs[0]);
501 }
502 binarySecurity.setID(certUri);
503 if (addWSUNamespace) {
504 binarySecurity.addWSUNamespace();
505 }
506 bstToken = binarySecurity.getElement();
507 getWsDocInfo().addTokenElement(bstToken, false);
508 }
509
510 bstAddedToSecurityHeader = false;
511 }
512
513
514
515
516
517
518
519
520
521 public void prependBSTElementToHeader() {
522 if (bstToken != null && !bstAddedToSecurityHeader) {
523 Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
524 WSSecurityUtil.prependChildElement(securityHeaderElement, bstToken);
525 bstAddedToSecurityHeader = true;
526 }
527 }
528
529
530
531
532 public void appendBSTElementToHeader() {
533 if (bstToken != null && !bstAddedToSecurityHeader) {
534 Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
535 securityHeaderElement.appendChild(bstToken);
536 bstAddedToSecurityHeader = true;
537 }
538 }
539
540
541
542
543
544
545
546
547
548
549
550
551 public void computeSignature(
552 List<javax.xml.crypto.dsig.Reference> referenceList
553 ) throws WSSecurityException {
554 computeSignature(referenceList, true, null);
555 }
556
557
558
559
560
561
562
563
564
565
566
567
568
569 public void computeSignature(
570 List<javax.xml.crypto.dsig.Reference> referenceList,
571 boolean prepend,
572 Element siblingElement
573 ) throws WSSecurityException {
574 try {
575 java.security.Key key;
576 if (secretKey == null) {
577 key = crypto.getPrivateKey(user, password);
578 } else {
579 key = KeyUtils.prepareSecretKey(sigAlgo, secretKey);
580 }
581 SignatureMethod signatureMethod =
582 signatureFactory.newSignatureMethod(sigAlgo, null);
583 SignedInfo signedInfo =
584 signatureFactory.newSignedInfo(c14nMethod, signatureMethod, referenceList);
585
586 sig = signatureFactory.newXMLSignature(
587 signedInfo,
588 keyInfo,
589 null,
590 getIdAllocator().createId("SIG-", null),
591 null);
592
593
594
595
596 XMLSignContext signContext = null;
597 Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
598 if (prepend) {
599 if (siblingElement == null) {
600 Node child = securityHeaderElement.getFirstChild();
601 while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
602 child = child.getNextSibling();
603 }
604 siblingElement = (Element)child;
605 }
606 if (siblingElement == null) {
607 signContext = new DOMSignContext(key, securityHeaderElement);
608 } else {
609 signContext = new DOMSignContext(key, securityHeaderElement, siblingElement);
610 }
611 } else {
612 signContext = new DOMSignContext(key, securityHeaderElement);
613 }
614 if (signatureProvider != null) {
615 signContext.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider", signatureProvider);
616 }
617
618 signContext.putNamespacePrefix(WSConstants.SIG_NS, WSConstants.SIG_PREFIX);
619 if (WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(canonAlgo)) {
620 signContext.putNamespacePrefix(
621 WSConstants.C14N_EXCL_OMIT_COMMENTS,
622 WSConstants.C14N_EXCL_OMIT_COMMENTS_PREFIX
623 );
624 }
625 signContext.setProperty(STRTransform.TRANSFORM_WS_DOC_INFO, getWsDocInfo());
626 getWsDocInfo().setCallbackLookup(callbackLookup);
627
628
629 getWsDocInfo().setTokensOnContext((DOMSignContext)signContext);
630 sig.sign(signContext);
631
632 signatureValue = sig.getSignatureValue().getValue();
633
634 cleanup();
635 } catch (Exception ex) {
636 LOG.error(ex.getMessage(), ex);
637 throw new WSSecurityException(
638 WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex
639 );
640 }
641 }
642
643
644
645
646
647
648 public void setUseSingleCertificate(boolean useSingleCert) {
649 this.useSingleCert = useSingleCert;
650 }
651
652
653
654
655
656
657 public boolean isUseSingleCertificate() {
658 return useSingleCert;
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672 public void setSignatureAlgorithm(String algo) {
673 sigAlgo = algo;
674 }
675
676
677
678
679
680
681
682
683
684
685 public String getSignatureAlgorithm() {
686 return sigAlgo;
687 }
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702 public void setSigCanonicalization(String algo) {
703 canonAlgo = algo;
704 }
705
706
707
708
709
710
711
712
713
714 public String getSigCanonicalization() {
715 return canonAlgo;
716 }
717
718
719
720
721 public String getDigestAlgo() {
722 return digestAlgo;
723 }
724
725
726
727
728
729
730
731 public void setDigestAlgo(String digestAlgo) {
732 this.digestAlgo = digestAlgo;
733 }
734
735
736
737
738
739
740
741
742
743
744 public byte[] getSignatureValue() {
745 return signatureValue;
746 }
747
748
749
750
751
752
753
754
755
756 public String getId() {
757 if (sig == null) {
758 return null;
759 }
760 return sig.getId();
761 }
762
763
764
765
766
767
768
769 public String getBSTTokenId() {
770 if (bstToken == null) {
771 return null;
772 }
773 return bstToken.getAttributeNS(WSS4JConstants.WSU_NS, "Id");
774 }
775
776
777
778
779
780 public void setSecretKey(byte[] secretKey) {
781 this.secretKey = secretKey;
782 }
783
784
785
786
787
788 public void setCustomTokenValueType(String customTokenValueType) {
789 this.customTokenValueType = customTokenValueType;
790 }
791
792
793
794
795
796 public void setCustomTokenId(String customTokenId) {
797 this.customTokenId = customTokenId;
798 }
799
800 public String getCustomTokenId() {
801 return this.customTokenId;
802 }
803
804
805
806
807
808 public void setEncrKeySha1value(String encrKeySha1value) {
809 this.encrKeySha1value = encrKeySha1value;
810 }
811
812
813
814
815
816 public void setX509Certificate(X509Certificate cer) {
817 this.useThisCert = cer;
818 }
819
820
821
822
823
824
825 public Element getBinarySecurityTokenElement() {
826 return bstToken;
827 }
828
829
830
831
832
833 public String getSecurityTokenReferenceURI() {
834 return strUri;
835 }
836
837
838
839
840 public SecurityTokenReference getSecurityTokenReference() {
841 return secRef;
842 }
843
844
845
846
847
848 public void setSecurityTokenReference(SecurityTokenReference secRef) {
849 useCustomSecRef = true;
850 this.secRef = secRef;
851 }
852
853
854
855
856 private X509Certificate[] getSigningCerts() throws WSSecurityException {
857 X509Certificate[] certs = null;
858 if (!(keyIdentifierType == WSConstants.CUSTOM_SYMM_SIGNING
859 || keyIdentifierType == WSConstants.CUSTOM_SYMM_SIGNING_DIRECT
860 || keyIdentifierType == WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER
861 || keyIdentifierType == WSConstants.CUSTOM_KEY_IDENTIFIER)) {
862 if (useThisCert == null) {
863 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
864 cryptoType.setAlias(user);
865 if (crypto == null) {
866 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noSigCryptoFile");
867 }
868 certs = crypto.getX509Certificates(cryptoType);
869 } else {
870 certs = new X509Certificate[] {useThisCert};
871 }
872 if (certs == null || certs.length <= 0) {
873 throw new WSSecurityException(
874 WSSecurityException.ErrorCode.FAILURE,
875 "noUserCertsFound",
876 new Object[] {user, "signature"});
877 }
878 certUri = getIdAllocator().createSecureId("X509-", certs[0]);
879
880
881
882
883 if (sigAlgo == null) {
884 String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();
885 LOG.debug("Automatic signature algorithm detection: {}", pubKeyAlgo);
886 if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
887 sigAlgo = WSConstants.DSA;
888 } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
889 sigAlgo = WSConstants.RSA;
890 } else if (pubKeyAlgo.equalsIgnoreCase("EC")) {
891 sigAlgo = WSConstants.ECDSA_SHA256;
892 } else if (pubKeyAlgo.equalsIgnoreCase("Ed25519")) {
893 sigAlgo = WSConstants.ED25519;
894 } else if (pubKeyAlgo.equalsIgnoreCase("ED448")) {
895 sigAlgo = WSConstants.ED448;
896 } else if (pubKeyAlgo.equalsIgnoreCase("EdDSA")) {
897 sigAlgo = getSigAlgorithmForEdDSAKey(certs[0].getPublicKey());
898 } else {
899 throw new WSSecurityException(
900 WSSecurityException.ErrorCode.FAILURE,
901 "unknownSignatureAlgorithm",
902 new Object[] {pubKeyAlgo});
903 }
904 }
905 }
906 return certs;
907 }
908
909
910
911
912
913
914
915
916 private static String getSigAlgorithmForEdDSAKey(PublicKey publicKey) throws WSSecurityException {
917
918 if (!"x.509".equalsIgnoreCase(publicKey.getFormat())) {
919 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unknownAlgorithm",
920 new Object[]{"Unknown cert format!"});
921 }
922
923 DERDecoder decoder = new DERDecoder(publicKey.getEncoded());
924
925 decoder.expect(decoder.TYPE_SEQUENCE);
926 decoder.getLength();
927 decoder.expect(decoder.TYPE_SEQUENCE);
928 decoder.getLength();
929 decoder.expect(decoder.TYPE_OBJECT_IDENTIFIER);
930 int size = decoder.getLength();
931 if (size != 3) {
932 LOG.debug("Invalid ECDSA Public key OID byte size: [{}]", size);
933 throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "invalidCert");
934 }
935
936
937
938 decoder.expect(43);
939
940 decoder.expect(101);
941
942 byte algDef = decoder.getBytes(1)[0];
943 switch (algDef) {
944 case 112:
945 return WSConstants.ED25519;
946 case 113:
947 return WSConstants.ED448;
948 default:
949 throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "unknownAlgorithm",
950 new Object[]{"Invalid ECDSA Public key OID!"});
951 }
952 }
953
954 public boolean isIncludeSignatureToken() {
955 return includeSignatureToken;
956 }
957
958 public void setIncludeSignatureToken(boolean includeSignatureToken) {
959 this.includeSignatureToken = includeSignatureToken;
960 }
961
962 public boolean isAddInclusivePrefixes() {
963 return addInclusivePrefixes;
964 }
965
966 public void setAddInclusivePrefixes(boolean addInclusivePrefixes) {
967 this.addInclusivePrefixes = addInclusivePrefixes;
968 }
969
970 public void setCustomKeyInfoElement(Element keyInfoElement) {
971 this.customKeyInfoElement = keyInfoElement;
972 }
973
974 public Element getCustomKeyInfoElement() {
975 return customKeyInfoElement;
976 }
977
978 public Provider getSignatureProvider() {
979 return signatureProvider;
980 }
981
982 public void setSignatureProvider(Provider signatureProvider) {
983 this.signatureProvider = signatureProvider;
984 }
985
986 public String getKeyInfoUri() {
987 return keyInfoUri;
988 }
989 }