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 org.apache.wss4j.common.WSS4JConstants;
23 import org.apache.wss4j.common.crypto.Crypto;
24 import org.apache.wss4j.common.crypto.CryptoType;
25 import org.apache.wss4j.common.ext.WSSecurityException;
26 import org.apache.wss4j.common.token.*;
27 import org.apache.wss4j.common.util.AttachmentUtils;
28 import org.apache.wss4j.common.util.KeyUtils;
29 import org.apache.wss4j.dom.WSConstants;
30 import org.apache.wss4j.dom.util.WSSecurityUtil;
31 import org.apache.xml.security.encryption.XMLCipherUtil;
32 import org.apache.xml.security.encryption.XMLEncryptionException;
33 import org.apache.xml.security.encryption.keys.content.AgreementMethodImpl;
34 import org.apache.xml.security.encryption.params.ConcatKDFParams;
35 import org.apache.xml.security.encryption.params.HKDFParams;
36 import org.apache.xml.security.encryption.params.KeyAgreementParameters;
37 import org.apache.xml.security.encryption.params.KeyDerivationParameters;
38 import org.apache.xml.security.exceptions.XMLSecurityException;
39 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
40 import org.apache.xml.security.stax.impl.util.IDGenerator;
41 import org.apache.xml.security.utils.Constants;
42 import org.apache.xml.security.utils.XMLUtils;
43 import org.w3c.dom.Document;
44 import org.w3c.dom.Element;
45 import org.w3c.dom.Text;
46
47 import javax.crypto.Cipher;
48 import javax.crypto.IllegalBlockSizeException;
49 import javax.crypto.SecretKey;
50 import javax.crypto.spec.OAEPParameterSpec;
51 import javax.xml.crypto.MarshalException;
52 import javax.xml.crypto.dom.DOMStructure;
53 import javax.xml.crypto.dsig.XMLSignatureFactory;
54 import javax.xml.crypto.dsig.keyinfo.KeyInfo;
55 import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
56 import javax.xml.crypto.dsig.keyinfo.KeyValue;
57 import java.security.*;
58 import java.security.cert.X509Certificate;
59
60
61
62
63
64
65
66
67
68
69 public class WSSecEncryptedKey extends WSSecBase {
70
71 private static final org.slf4j.Logger LOG =
72 org.slf4j.LoggerFactory.getLogger(WSSecEncryptedKey.class);
73
74
75
76
77 private String keyEncAlgo = WSConstants.KEYTRANSPORT_RSAOAEP;
78
79
80
81
82
83
84
85 private String keyAgreementMethod;
86
87
88
89
90
91 private String keyDerivationMethod = WSS4JConstants.KEYDERIVATION_HKDF;
92
93
94
95
96
97 private KeyDerivationParameters keyDerivationParameters;
98
99
100
101
102
103 private String digestAlgo;
104
105
106
107
108
109 private String mgfAlgo;
110
111
112
113
114 private Element encryptedKeyElement;
115
116
117
118
119
120 private String encKeyId;
121
122
123
124
125
126 private BinarySecurity bstToken;
127
128 private X509Certificate useThisCert;
129
130 private PublicKey useThisPublicKey;
131
132
133
134
135 private String customEKTokenValueType;
136
137
138
139
140 private String customEKTokenId;
141
142 private boolean bstAddedToSecurityHeader;
143 private boolean includeEncryptionToken;
144 private Element customEKKeyInfoElement;
145 private Provider provider;
146
147 private String encryptedKeySHA1;
148
149 public WSSecEncryptedKey(WSSecHeader securityHeader) {
150 super(securityHeader);
151 }
152
153 public WSSecEncryptedKey(Document doc) {
154 this(doc, null);
155 }
156
157 public WSSecEncryptedKey(Document doc, Provider provider) {
158 super(doc);
159 this.provider = provider;
160 }
161
162
163
164
165
166
167
168
169
170 public void setUserInfo(String user) {
171 this.user = user;
172 }
173
174
175
176
177
178
179
180
181
182 public String getId() {
183 return encKeyId;
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197 public void prepare(Crypto crypto, SecretKey symmetricKey) throws WSSecurityException {
198
199 if (useThisPublicKey != null) {
200 createEncryptedKeyElement(useThisPublicKey);
201 byte[] encryptedEphemeralKey = encryptSymmetricKey(useThisPublicKey, symmetricKey);
202 addCipherValueElement(encryptedEphemeralKey);
203 } else {
204
205
206
207
208 X509Certificate remoteCert = useThisCert;
209 if (remoteCert == null) {
210 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
211 cryptoType.setAlias(user);
212 if (crypto == null) {
213 throw new WSSecurityException(
214 WSSecurityException.ErrorCode.FAILURE,
215 "noUserCertsFound",
216 new Object[] {user, "encryption"});
217 }
218 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
219 if (certs == null || certs.length <= 0) {
220 throw new WSSecurityException(
221 WSSecurityException.ErrorCode.FAILURE,
222 "noUserCertsFound",
223 new Object[] {user, "encryption"});
224 }
225 remoteCert = certs[0];
226 }
227
228 Key kek;
229 KeyAgreementParameters dhSpec = null;
230 if (isKeyAgreementConfigured(keyAgreementMethod)) {
231
232 dhSpec = buildKeyAgreementParameter(remoteCert.getPublicKey());
233 kek = generateEncryptionKey(dhSpec);
234 } else {
235 kek = remoteCert.getPublicKey();
236 }
237
238 createEncryptedKeyElement(remoteCert, crypto, dhSpec);
239 byte[] encryptedEphemeralKey = encryptSymmetricKey(kek, symmetricKey);
240 addCipherValueElement(encryptedEphemeralKey);
241 }
242 }
243
244
245
246
247 protected void addCipherValueElement(byte[] encryptedEphemeralKey) throws WSSecurityException {
248 Element xencCipherValue = createCipherValue(getDocument(), encryptedKeyElement);
249 if (storeBytesInAttachment) {
250 final String attachmentId = getIdAllocator().createId("", getDocument());
251 AttachmentUtils.storeBytesInAttachment(xencCipherValue, getDocument(), attachmentId,
252 encryptedEphemeralKey, attachmentCallbackHandler);
253 } else {
254 Text keyText =
255 WSSecurityUtil.createBase64EncodedTextNode(getDocument(), encryptedEphemeralKey);
256 xencCipherValue.appendChild(keyText);
257 }
258
259 setEncryptedKeySHA1(encryptedEphemeralKey);
260 }
261
262
263
264
265
266
267
268
269 protected void createEncryptedKeyElement(X509Certificate remoteCert, Crypto crypto, KeyAgreementParameters dhSpec)
270 throws WSSecurityException {
271 encryptedKeyElement = createEncryptedKey(getDocument(), keyEncAlgo);
272 if (encKeyId == null || encKeyId.isEmpty()) {
273 encKeyId = IDGenerator.generateID("EK-");
274 }
275 encryptedKeyElement.setAttributeNS(null, "Id", encKeyId);
276
277 if (customEKKeyInfoElement != null) {
278 encryptedKeyElement.appendChild(getDocument().adoptNode(customEKKeyInfoElement));
279 } else if (keyIdentifierType == WSConstants.X509_SKI) {
280 DOMX509SKI x509SKI = new DOMX509SKI(getDocument(), remoteCert);
281 DOMX509Data x509Data = new DOMX509Data(getDocument(), x509SKI);
282
283 Element keyInfoElement = createKeyInfoElement(x509Data.getElement(), dhSpec);
284 encryptedKeyElement.appendChild(keyInfoElement);
285 } else {
286 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
287 if (addWSUNamespace) {
288 secToken.addWSUNamespace();
289 }
290
291 switch (keyIdentifierType) {
292 case WSConstants.X509_KEY_IDENTIFIER:
293 secToken.setKeyIdentifier(remoteCert);
294 break;
295
296 case WSConstants.SKI_KEY_IDENTIFIER:
297 secToken.setKeyIdentifierSKI(remoteCert, crypto);
298
299 if (includeEncryptionToken) {
300 addBST(remoteCert);
301 }
302 break;
303
304 case WSConstants.THUMBPRINT_IDENTIFIER:
305 case WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER:
306
307
308
309
310 secToken.setKeyIdentifierThumb(remoteCert);
311
312 if (includeEncryptionToken) {
313 addBST(remoteCert);
314 }
315 break;
316
317 case WSConstants.ISSUER_SERIAL:
318 addIssuerSerial(remoteCert, secToken, false);
319 break;
320
321 case WSConstants.ISSUER_SERIAL_QUOTE_FORMAT:
322 addIssuerSerial(remoteCert, secToken,true);
323 break;
324
325 case WSConstants.BST_DIRECT_REFERENCE:
326 Reference ref = new Reference(getDocument());
327 String certUri = IDGenerator.generateID(null);
328 ref.setURI("#" + certUri);
329 bstToken = new X509Security(getDocument());
330 ((X509Security) bstToken).setX509Certificate(remoteCert);
331 bstToken.setID(certUri);
332 ref.setValueType(bstToken.getValueType());
333 secToken.setReference(ref);
334 break;
335
336 case WSConstants.CUSTOM_SYMM_SIGNING :
337 Reference refCust = new Reference(getDocument());
338 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
339 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
340 refCust.setValueType(customEKTokenValueType);
341 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
342 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
343 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
344 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
345 refCust.setValueType(customEKTokenValueType);
346 } else {
347 refCust.setValueType(customEKTokenValueType);
348 }
349 refCust.setURI("#" + customEKTokenId);
350 secToken.setReference(refCust);
351 break;
352
353 case WSConstants.CUSTOM_SYMM_SIGNING_DIRECT :
354 Reference refCustd = new Reference(getDocument());
355 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
356 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
357 refCustd.setValueType(customEKTokenValueType);
358 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
359 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
360 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
361 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
362 refCustd.setValueType(customEKTokenValueType);
363 } else {
364 refCustd.setValueType(customEKTokenValueType);
365 }
366 refCustd.setURI(customEKTokenId);
367 secToken.setReference(refCustd);
368 break;
369
370 case WSConstants.CUSTOM_KEY_IDENTIFIER:
371 secToken.setKeyIdentifier(customEKTokenValueType, customEKTokenId);
372 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
373 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
374 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
375 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
376 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
377 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
378 } else if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(customEKTokenValueType)) {
379 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
380 }
381 break;
382
383 default:
384 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId",
385 new Object[] {keyIdentifierType});
386 }
387
388 Element keyInfoElement = createKeyInfoElement(secToken.getElement(), dhSpec);
389 encryptedKeyElement.appendChild(keyInfoElement);
390 }
391 }
392
393
394
395
396 private Element createKeyInfoElement(Element childElement, KeyAgreementParameters dhSpec) throws WSSecurityException {
397 Element keyInfoElement =
398 getDocument().createElementNS(
399 WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
400 );
401 keyInfoElement.setAttributeNS(
402 WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
403 );
404 if (isKeyAgreementConfigured(keyAgreementMethod)) {
405 try {
406 AgreementMethodImpl agreementMethod = new AgreementMethodImpl(getDocument(), dhSpec);
407 agreementMethod.getRecipientKeyInfo().addUnknownElement(childElement);
408 Element agreementMethodElement = agreementMethod.getElement();
409 keyInfoElement.appendChild(agreementMethodElement);
410 } catch (XMLSecurityException e) {
411 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId",
412 new Object[] {keyIdentifierType});
413 }
414
415 } else {
416 keyInfoElement.appendChild(childElement);
417 }
418 return keyInfoElement;
419 }
420
421
422
423
424
425
426 private boolean isKeyAgreementConfigured(String keyAgreementMethod) {
427 return keyAgreementMethod != null && !keyAgreementMethod.isEmpty();
428 }
429
430 private void addIssuerSerial(X509Certificate remoteCert, SecurityTokenReference secToken, boolean isCommaDelimited)
431 throws WSSecurityException {
432 String issuer = remoteCert.getIssuerX500Principal().getName();
433 java.math.BigInteger serialNumber = remoteCert.getSerialNumber();
434 DOMX509IssuerSerial domIssuerSerial =
435 new DOMX509IssuerSerial(getDocument(), issuer, serialNumber, isCommaDelimited);
436 DOMX509Data domX509Data = new DOMX509Data(getDocument(), domIssuerSerial);
437 secToken.setUnknownElement(domX509Data.getElement());
438
439 if (includeEncryptionToken) {
440 addBST(remoteCert);
441 }
442 }
443
444
445
446
447
448
449
450
451 protected void createEncryptedKeyElement(Key key) throws WSSecurityException {
452 encryptedKeyElement = createEncryptedKey(getDocument(), keyEncAlgo);
453 if (encKeyId == null || encKeyId.isEmpty()) {
454 encKeyId = IDGenerator.generateID("EK-");
455 }
456 encryptedKeyElement.setAttributeNS(null, "Id", encKeyId);
457
458 if (customEKKeyInfoElement != null) {
459 encryptedKeyElement.appendChild(getDocument().adoptNode(customEKKeyInfoElement));
460 } else {
461 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
462 if (addWSUNamespace) {
463 secToken.addWSUNamespace();
464 }
465
466 switch (keyIdentifierType) {
467
468 case WSConstants.CUSTOM_SYMM_SIGNING :
469 Reference refCust = new Reference(getDocument());
470 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
471 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
472 refCust.setValueType(customEKTokenValueType);
473 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
474 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
475 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
476 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
477 refCust.setValueType(customEKTokenValueType);
478 } else {
479 refCust.setValueType(customEKTokenValueType);
480 }
481 refCust.setURI("#" + customEKTokenId);
482 secToken.setReference(refCust);
483 break;
484
485 case WSConstants.CUSTOM_SYMM_SIGNING_DIRECT :
486 Reference refCustd = new Reference(getDocument());
487 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
488 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
489 refCustd.setValueType(customEKTokenValueType);
490 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
491 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
492 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
493 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
494 refCustd.setValueType(customEKTokenValueType);
495 } else {
496 refCustd.setValueType(customEKTokenValueType);
497 }
498 refCustd.setURI(customEKTokenId);
499 secToken.setReference(refCustd);
500 break;
501
502 case WSConstants.CUSTOM_KEY_IDENTIFIER:
503 secToken.setKeyIdentifier(customEKTokenValueType, customEKTokenId);
504 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
505 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
506 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
507 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
508 } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
509 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
510 } else if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(customEKTokenValueType)) {
511 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
512 }
513 break;
514
515 case WSConstants.KEY_VALUE:
516
517 if (!(key instanceof PublicKey)) {
518 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId",
519 new Object[] {keyIdentifierType});
520 }
521 try {
522 XMLSignatureFactory signatureFactory;
523 if (provider == null) {
524
525
526 try {
527 signatureFactory = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
528 } catch (NoSuchProviderException ex) {
529 signatureFactory = XMLSignatureFactory.getInstance("DOM");
530 }
531 } else {
532 signatureFactory = XMLSignatureFactory.getInstance("DOM", provider);
533 }
534
535 KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
536 KeyValue keyValue = keyInfoFactory.newKeyValue((PublicKey)key);
537 String keyInfoUri = getIdAllocator().createSecureId("KI-", null);
538 KeyInfo keyInfo =
539 keyInfoFactory.newKeyInfo(
540 java.util.Collections.singletonList(keyValue), keyInfoUri
541 );
542
543 keyInfo.marshal(new DOMStructure(encryptedKeyElement), null);
544 } catch (java.security.KeyException | MarshalException ex) {
545 LOG.error("", ex);
546 throw new WSSecurityException(
547 WSSecurityException.ErrorCode.FAILED_ENCRYPTION, ex
548 );
549 }
550 break;
551
552 default:
553 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId",
554 new Object[] {keyIdentifierType});
555 }
556
557 if (WSConstants.KEY_VALUE != keyIdentifierType) {
558 Element keyInfoElement =
559 getDocument().createElementNS(
560 WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
561 );
562 keyInfoElement.setAttributeNS(
563 WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
564 );
565 keyInfoElement.appendChild(secToken.getElement());
566 encryptedKeyElement.appendChild(keyInfoElement);
567 }
568 }
569 }
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584 private KeyAgreementParameters buildKeyAgreementParameter(PublicKey recipientPublicKey)
585 throws WSSecurityException {
586 KeyAgreementParameters dhSpec;
587 try {
588 int keyBitLength = org.apache.xml.security.utils.KeyUtils.getAESKeyBitSizeForWrapAlgorithm(keyEncAlgo);
589 KeyDerivationParameters kdf = keyDerivationParameters;
590 if (keyDerivationParameters == null) {
591 LOG.debug("Set default KeyDerivationParameters for key derivation method: [{}]",
592 keyDerivationMethod);
593 kdf = buildDefaultKeyDerivationParameters(keyBitLength);
594 }
595 KeyPair dhKeyPair = org.apache.xml.security.utils.KeyUtils.generateEphemeralDHKeyPair(recipientPublicKey, null);
596 dhSpec = XMLCipherUtil.constructAgreementParameters(keyAgreementMethod,
597 KeyAgreementParameters.ActorType.ORIGINATOR, kdf, null, recipientPublicKey);
598 dhSpec.setOriginatorKeyPair(dhKeyPair);
599 } catch (XMLEncryptionException e) {
600 throw new WSSecurityException(
601 WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e
602 );
603 }
604 return dhSpec;
605 }
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634 private KeyDerivationParameters buildDefaultKeyDerivationParameters(int keyBitLength) throws WSSecurityException {
635
636 switch (keyDerivationMethod) {
637 case WSS4JConstants.KEYDERIVATION_CONCATKDF:
638 return ConcatKDFParams.createBuilder(keyBitLength, WSConstants.SHA256)
639 .algorithmID("0000")
640 .partyUInfo("")
641 .partyVInfo("")
642 .build();
643 case WSS4JConstants.KEYDERIVATION_HKDF:
644
645
646
647
648 byte[] semiRandom;
649 try {
650 int length = keyBitLength / 8;
651 semiRandom = XMLSecurityConstants.generateBytes(length);
652 } catch (Exception ex) {
653 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, ex,
654 "empty", new Object[] {"Error in generating secret bytes " }
655 );
656 }
657 return HKDFParams.createBuilder(keyBitLength, WSS4JConstants.HMAC_SHA256)
658 .salt(semiRandom)
659 .info(null)
660 .build();
661 default:
662 throw new WSSecurityException(
663 WSSecurityException.ErrorCode.FAILED_ENCRYPTION, "unsupportedKeyDerivationMethod",
664 new Object[]{keyDerivationMethod}
665 );
666 }
667 }
668
669
670
671
672
673
674
675
676
677 private SecretKey generateEncryptionKey(KeyAgreementParameters keyAgreementParameter) throws WSSecurityException {
678 try {
679
680 return org.apache.xml.security.utils.KeyUtils.aesWrapKeyWithDHGeneratedKey(keyAgreementParameter);
681 } catch (XMLEncryptionException e) {
682 throw new WSSecurityException(
683 WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e
684 );
685 }
686 }
687
688 private byte[] encryptSymmetricKey(Key encryptingKey, SecretKey keyToBeEncrypted)
689 throws WSSecurityException {
690 Cipher cipher = KeyUtils.getCipherInstance(keyEncAlgo);
691 try {
692 OAEPParameterSpec oaepParameterSpec = null;
693 if (WSConstants.KEYTRANSPORT_RSAOAEP.equals(keyEncAlgo)
694 || WSConstants.KEYTRANSPORT_RSAOAEP_XENC11.equals(keyEncAlgo)) {
695 oaepParameterSpec = XMLCipherUtil.constructOAEPParameters(keyEncAlgo, digestAlgo, mgfAlgo, null);
696 }
697 if (oaepParameterSpec == null) {
698 cipher.init(Cipher.WRAP_MODE, encryptingKey);
699 } else {
700 cipher.init(Cipher.WRAP_MODE, encryptingKey, oaepParameterSpec);
701 }
702 } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
703 throw new WSSecurityException(
704 WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e
705 );
706 }
707 int blockSize = cipher.getBlockSize();
708 LOG.debug("cipher blksize: {}", blockSize);
709
710 try {
711 return cipher.wrap(keyToBeEncrypted);
712 } catch (IllegalStateException | IllegalBlockSizeException | InvalidKeyException ex) {
713 throw new WSSecurityException(
714 WSSecurityException.ErrorCode.FAILED_ENCRYPTION, ex
715 );
716 }
717 }
718
719
720
721
722 private void addBST(X509Certificate cert) throws WSSecurityException {
723 bstToken = new X509Security(getDocument());
724 ((X509Security) bstToken).setX509Certificate(cert);
725
726 bstAddedToSecurityHeader = false;
727 bstToken.setID(IDGenerator.generateID(null));
728 if (addWSUNamespace) {
729 bstToken.addWSUNamespace();
730 }
731 }
732
733
734
735
736
737
738
739
740 private Element createEncryptedKey(Document doc, String keyTransportAlgo) {
741 Element encryptedKey =
742 doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptedKey");
743
744 org.apache.wss4j.common.util.XMLUtils.setNamespace(encryptedKey, WSConstants.ENC_NS, WSConstants.ENC_PREFIX);
745 Element encryptionMethod =
746 doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptionMethod");
747 encryptionMethod.setAttributeNS(null, "Algorithm", keyTransportAlgo);
748
749 if ((WSConstants.KEYTRANSPORT_RSAOAEP_XENC11.equals(keyEncAlgo) || WSConstants.KEYTRANSPORT_RSAOAEP.equals(
750 keyEncAlgo)) && digestAlgo != null) {
751 Element digestElement =
752 XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_DIGESTMETHOD);
753 digestElement.setAttributeNS(null, "Algorithm", digestAlgo);
754 encryptionMethod.appendChild(digestElement);
755 }
756 if (WSConstants.KEYTRANSPORT_RSAOAEP_XENC11.equals(keyEncAlgo) && mgfAlgo != null) {
757 Element mgfElement =
758 doc.createElementNS(WSConstants.ENC11_NS, WSConstants.ENC11_PREFIX + ":MGF");
759 mgfElement.setAttributeNS(null, "Algorithm", mgfAlgo);
760 encryptionMethod.appendChild(mgfElement);
761 }
762
763 encryptedKey.appendChild(encryptionMethod);
764 return encryptedKey;
765 }
766
767 protected Element createCipherValue(Document doc, Element encryptedKey) {
768 Element cipherData =
769 doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherData");
770 Element cipherValue =
771 doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherValue");
772 cipherData.appendChild(cipherValue);
773 encryptedKey.appendChild(cipherData);
774 return cipherValue;
775 }
776
777
778
779
780
781
782
783
784
785 public void prependToHeader() {
786 Element secHeaderElement = getSecurityHeader().getSecurityHeaderElement();
787 WSSecurityUtil.prependChildElement(secHeaderElement, encryptedKeyElement);
788 }
789
790
791
792
793
794
795
796
797
798 public void appendToHeader() {
799 Element secHeaderElement = getSecurityHeader().getSecurityHeaderElement();
800 secHeaderElement.appendChild(encryptedKeyElement);
801 }
802
803
804
805
806
807
808
809
810 public void prependBSTElementToHeader() {
811 if (bstToken != null && !bstAddedToSecurityHeader) {
812 Element secHeaderElement = getSecurityHeader().getSecurityHeaderElement();
813 WSSecurityUtil.prependChildElement(secHeaderElement, bstToken.getElement());
814 bstAddedToSecurityHeader = true;
815 }
816 }
817
818
819
820
821
822
823
824
825 public void appendBSTElementToHeader() {
826 if (bstToken != null && !bstAddedToSecurityHeader) {
827 Element secHeaderElement = getSecurityHeader().getSecurityHeaderElement();
828 secHeaderElement.appendChild(bstToken.getElement());
829 bstAddedToSecurityHeader = true;
830 }
831 }
832
833
834
835
836
837
838
839
840
841
842 public void setUseThisCert(X509Certificate cert) {
843 useThisCert = cert;
844 }
845
846 public X509Certificate getUseThisCert() {
847 return useThisCert;
848 }
849
850
851
852
853
854 public void setUseThisPublicKey(PublicKey key) {
855 useThisPublicKey = key;
856 }
857
858 public PublicKey getUseThisPublicKey() {
859 return useThisPublicKey;
860 }
861
862
863
864
865 public Element getEncryptedKeyElement() {
866 return encryptedKeyElement;
867 }
868
869
870
871
872
873 public void setEncryptedKeyElement(Element encryptedKeyElement) {
874 this.encryptedKeyElement = encryptedKeyElement;
875 }
876
877
878
879
880 public Element getBinarySecurityTokenElement() {
881 if (bstToken != null) {
882 return bstToken.getElement();
883 }
884 return null;
885 }
886
887 public void setKeyEncAlgo(String keyEncAlgo) {
888 this.keyEncAlgo = keyEncAlgo;
889 }
890
891 public String getKeyEncAlgo() {
892 return keyEncAlgo;
893 }
894
895 public String getKeyAgreementMethod() {
896 return keyAgreementMethod;
897 }
898
899 public void setKeyAgreementMethod(String keyAgreementMethod) {
900 this.keyAgreementMethod = keyAgreementMethod;
901 }
902
903 public String getKeyDerivationMethod() {
904 return keyDerivationMethod;
905 }
906
907 public void setKeyDerivationMethod(String keyDerivationMethod) {
908 this.keyDerivationMethod = keyDerivationMethod;
909 }
910
911 public KeyDerivationParameters getKeyDerivationParameters() {
912 return keyDerivationParameters;
913 }
914
915 public void setKeyDerivationParameters(KeyDerivationParameters keyDerivationParameters) {
916 this.keyDerivationParameters = keyDerivationParameters;
917 }
918
919
920
921
922
923
924
925 public String getBSTTokenId() {
926 if (bstToken == null) {
927 return null;
928 }
929
930 return bstToken.getID();
931 }
932
933
934
935
936 public void setEncKeyId(String encKeyId) {
937 this.encKeyId = encKeyId;
938 }
939
940 public boolean isCertSet() {
941 return useThisCert != null;
942 }
943
944 public void setCustomEKTokenValueType(String customEKTokenValueType) {
945 this.customEKTokenValueType = customEKTokenValueType;
946 }
947
948 public void setCustomEKTokenId(String customEKTokenId) {
949 this.customEKTokenId = customEKTokenId;
950 }
951
952
953
954
955
956
957
958 public void setDigestAlgorithm(String digestAlgorithm) {
959 this.digestAlgo = digestAlgorithm;
960 }
961
962
963
964
965
966 public String getDigestAlgorithm() {
967 return digestAlgo;
968 }
969
970
971
972
973
974
975
976 public void setMGFAlgorithm(String mgfAlgorithm) {
977 this.mgfAlgo = mgfAlgorithm;
978 }
979
980
981
982
983
984 public String getMGFAlgorithm() {
985 return mgfAlgo;
986 }
987
988 public boolean isIncludeEncryptionToken() {
989 return includeEncryptionToken;
990 }
991
992 public void setIncludeEncryptionToken(boolean includeEncryptionToken) {
993 this.includeEncryptionToken = includeEncryptionToken;
994 }
995
996 public Element getCustomEKKeyInfoElement() {
997 return customEKKeyInfoElement;
998 }
999
1000 public void setCustomEKKeyInfoElement(Element customEKKeyInfoElement) {
1001 this.customEKKeyInfoElement = customEKKeyInfoElement;
1002 }
1003
1004 protected void setEncryptedKeySHA1(byte[] encryptedEphemeralKey) throws WSSecurityException {
1005 byte[] encodedBytes = KeyUtils.generateDigest(encryptedEphemeralKey);
1006 encryptedKeySHA1 = XMLUtils.encodeToString(encodedBytes);
1007 }
1008
1009 public String getEncryptedKeySHA1() {
1010 return encryptedKeySHA1;
1011 }
1012 }