com.sun.xml.ws.security.trust.impl.SBIssuedSamlTokenContractImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of webservices-rt Show documentation
Show all versions of webservices-rt Show documentation
This module contains the Metro runtime code.
/*
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package com.sun.xml.ws.security.trust.impl;
import com.sun.xml.ws.api.security.trust.STSAttributeProvider;
import com.sun.xml.security.core.dsig.ObjectFactory;
import com.sun.xml.security.core.xenc.CipherDataType;
import com.sun.xml.security.core.xenc.EncryptedDataType;
import com.sun.xml.security.core.xenc.EncryptionMethodType;
import com.sun.xml.ws.api.SOAPVersion;
import com.sun.xml.ws.security.IssuedTokenContext;
import com.sun.xml.ws.security.opt.api.SecurityElement;
import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
import com.sun.xml.ws.security.opt.api.keyinfo.SecurityTokenReference;
import com.sun.xml.ws.security.opt.crypto.dsig.Signature;
import com.sun.xml.ws.security.opt.crypto.dsig.keyinfo.DSAKeyValue;
import com.sun.xml.ws.security.opt.crypto.dsig.keyinfo.KeyInfo;
import com.sun.xml.ws.security.opt.crypto.dsig.keyinfo.RSAKeyValue;
import com.sun.xml.ws.security.opt.crypto.dsig.keyinfo.X509Data;
import com.sun.xml.ws.security.opt.crypto.jaxb.JAXBSignContext;
import com.sun.xml.ws.security.opt.crypto.jaxb.JAXBSignatureFactory;
import com.sun.xml.ws.security.opt.impl.crypto.SSEData;
import com.sun.xml.ws.security.opt.impl.dsig.EnvelopedSignedMessageHeader;
import com.sun.xml.ws.security.opt.impl.dsig.JAXBSignatureHeaderElement;
import com.sun.xml.ws.security.opt.impl.enc.JAXBEncryptedData;
import com.sun.xml.ws.security.opt.impl.keyinfo.SAMLToken;
import com.sun.xml.ws.security.opt.impl.reference.KeyIdentifier;
import com.sun.xml.ws.security.opt.impl.util.NamespaceContextEx;
import com.sun.xml.ws.security.opt.impl.util.WSSElementFactory;
import com.sun.xml.wss.impl.MessageConstants;
import com.sun.xml.wss.saml.NameID;
import com.sun.xml.wss.saml.util.SAMLJAXBUtil;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.sun.xml.ws.security.opt.api.EncryptedKey;
import javax.crypto.spec.SecretKeySpec;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.crypto.Data;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.URIReference;
import javax.xml.crypto.URIReferenceException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignContext;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import com.sun.xml.ws.api.security.trust.WSTrustException;
import com.sun.xml.ws.api.security.trust.config.TrustSPMetadata;
import com.sun.xml.ws.security.Token;
import com.sun.xml.ws.security.trust.GenericToken;
import com.sun.xml.ws.security.trust.WSTrustConstants;
import com.sun.xml.ws.security.trust.util.WSTrustUtil;
import com.sun.xml.ws.security.trust.elements.BinarySecret;
import com.sun.xml.wss.impl.callback.EncryptionKeyCallback;
import com.sun.xml.wss.impl.callback.SignatureKeyCallback;
import com.sun.xml.wss.XWSSecurityException;
import com.sun.xml.wss.saml.Advice;
import com.sun.xml.wss.saml.Assertion;
import com.sun.xml.wss.saml.Attribute;
import com.sun.xml.wss.saml.AttributeStatement;
import com.sun.xml.wss.saml.Conditions;
import com.sun.xml.wss.saml.NameIdentifier;
import com.sun.xml.wss.saml.SAMLAssertionFactory;
import com.sun.xml.wss.saml.SAMLException;
import com.sun.xml.wss.saml.SubjectConfirmation;
import com.sun.xml.wss.saml.SubjectConfirmationData;
import javax.security.auth.callback.UnsupportedCallbackException;
import jakarta.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.xml.ws.security.trust.logging.LogDomainConstants;
import com.sun.xml.ws.security.trust.logging.LogStringsMessages;
/**
*
* @author
*/
public class SBIssuedSamlTokenContractImpl extends IssueSamlTokenContract{
//move to base class
private static final String SAML_HOLDER_OF_KEY = "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key";
protected static final String PRINCIPAL = "principal";
private SOAPVersion soapVersion = SOAPVersion.SOAP_11;
WSSElementFactory wef = new WSSElementFactory(SOAPVersion.SOAP_11);//TODO:: Pick up proper SOAPVersion.
private static final Logger log =
Logger.getLogger(
LogDomainConstants.TRUST_IMPL_DOMAIN,
LogDomainConstants.TRUST_IMPL_DOMAIN_BUNDLE);
/** Creates a new instance of SBIssuedSamlTokenContractImpl */
public SBIssuedSamlTokenContractImpl(SOAPVersion soapVersion) {
this.soapVersion = soapVersion;
}
public SBIssuedSamlTokenContractImpl() {
//constructor
}
public Token createSAMLAssertion(final String appliesTo, final String tokenType, final String keyType, final String assertionId, final String issuer, final Map> claimedAttrs, final IssuedTokenContext context) throws WSTrustException {
Token token = null;
final CallbackHandler callbackHandler = stsConfig.getCallbackHandler();
try{
NamespaceContextEx nsContext = null;
if(soapVersion == soapVersion.SOAP_11){
nsContext = new NamespaceContextEx();
}else{
nsContext = new NamespaceContextEx(true);
}
nsContext.addEncryptionNS();
nsContext.addExc14NS();
nsContext.addSAMLNS();
nsContext.addSignatureNS();
nsContext.addWSSNS();
// Get the service certificate
final X509Certificate serCert = getServiceCertificate(callbackHandler, stsConfig.getTrustSPMetadata(appliesTo), appliesTo);
// Create the KeyInfo for SubjectConfirmation
final KeyInfo keyInfo = createKeyInfo(keyType, serCert, context);
// Create SAML assertion
Assertion assertion = null;
SAMLToken samlToken = null;
if (WSTrustConstants.SAML10_ASSERTION_TOKEN_TYPE.equals(tokenType)||
WSTrustConstants.SAML11_ASSERTION_TOKEN_TYPE.equals(tokenType)){
assertion = createSAML11Assertion(assertionId, issuer, appliesTo, keyInfo, claimedAttrs);
samlToken = new SAMLToken(assertion,SAMLJAXBUtil.getJAXBContext(),soapVersion);
} else if (WSTrustConstants.SAML20_ASSERTION_TOKEN_TYPE.equals(tokenType)){
assertion = createSAML20Assertion(assertionId, issuer, appliesTo, keyInfo, claimedAttrs);
samlToken = new SAMLToken(assertion,SAMLJAXBUtil.getJAXBContext(),soapVersion);
} else{
log.log(Level.SEVERE,
LogStringsMessages.WST_0031_UNSUPPORTED_TOKEN_TYPE(tokenType, appliesTo));
throw new WSTrustException(LogStringsMessages.WST_0031_UNSUPPORTED_TOKEN_TYPE(tokenType, appliesTo));
}
// Get the STS's public and private key
final SignatureKeyCallback.DefaultPrivKeyCertRequest request =
new SignatureKeyCallback.DefaultPrivKeyCertRequest();
final Callback skc = new SignatureKeyCallback(request);
final Callback[] callbacks = {skc};
callbackHandler.handle(callbacks);
final PrivateKey stsPrivKey = request.getPrivateKey();
// Sign the assertion with STS's private key
//Element signedAssertion = assertion.sign(request.getX509Certificate(), stsPrivKey);
final SecurityHeaderElement signedAssertion = createSignature(request.getX509Certificate().getPublicKey(),stsPrivKey,samlToken,nsContext);
//jakarta.xml.bind.Unmarshaller u = eleFac.getContext().createUnmarshaller();
//JAXBElement aType = u.unmarshal(signedAssertion, AssertionType.class);
//assertion = new com.sun.xml.wss.saml.assertion.saml11.jaxb20.Assertion(aType.getValue());
token = new GenericToken(signedAssertion);
if (stsConfig.getEncryptIssuedToken()){
final String id = "uuid-" + UUID.randomUUID().toString();
final int keysizeInBytes = 32;
final byte[] skey = WSTrustUtil.generateRandomSecret(keysizeInBytes);
final Key key = new SecretKeySpec(skey, "AES");
final KeyInfo encKeyInfo = new KeyInfo();
final EncryptedKey encKey = encryptKey(key, serCert);
encKeyInfo.getContent().add(encKey);
final EncryptedDataType edt = createEncryptedData(id,MessageConstants.AES_BLOCK_ENCRYPTION_256,encKeyInfo,false);
final JAXBEncryptedData jed = new JAXBEncryptedData(edt,new SSEData((SecurityElement)signedAssertion,false,nsContext),soapVersion);
token = new GenericToken(jed);
}else{
token = new GenericToken(signedAssertion);
}
} catch (XWSSecurityException ex){
log.log(Level.SEVERE,
LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
throw new WSTrustException(LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
}catch (Exception ex) {
log.log(Level.SEVERE,
LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
throw new WSTrustException(LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
}
return token;
}
private Assertion createSAML11Assertion(final String assertionId, final String issuer, final String appliesTo, final KeyInfo keyInfo, final Map> claimedAttrs) throws WSTrustException{
Assertion assertion = null;
try{
final SAMLAssertionFactory samlFac = SAMLAssertionFactory.newInstance(SAMLAssertionFactory.SAML1_1);
final GregorianCalendar issuerInst = new GregorianCalendar();
final GregorianCalendar notOnOrAfter = new GregorianCalendar();
notOnOrAfter.add(Calendar.MILLISECOND, (int)stsConfig.getIssuedTokenTimeout());
final Conditions conditions =
samlFac.createConditions(issuerInst, notOnOrAfter, null, null, null);
final Advice advice = samlFac.createAdvice(null, null, null);
final List confirmMethods = new ArrayList();
confirmMethods.add(SAML_HOLDER_OF_KEY);
final SubjectConfirmation subjectConfirm = samlFac.createSubjectConfirmation(confirmMethods,null, keyInfo);
com.sun.xml.wss.saml.Subject subj = null;
final List attrs = new ArrayList();
final Set>> entries = claimedAttrs.entrySet();
for(Map.Entry> entry : entries){
final QName attrKey = (QName)entry.getKey();
final List values = (List)entry.getValue();
if (values != null && values.size() > 0){
if (STSAttributeProvider.NAME_IDENTIFIER.equals(attrKey.getLocalPart()) && subj == null){
final NameIdentifier nameId = samlFac.createNameIdentifier(values.get(0), attrKey.getNamespaceURI(), null);
subj = samlFac.createSubject(nameId, subjectConfirm);
}
else{
final Attribute attr = samlFac.createAttribute(attrKey.getLocalPart(), attrKey.getNamespaceURI(), values);
attrs.add(attr);
}
}
}
final AttributeStatement statement = samlFac.createAttributeStatement(subj, attrs);
final List statements = new ArrayList();
statements.add(statement);
assertion =
samlFac.createAssertion(assertionId, issuer, issuerInst, conditions, advice, statements);
}catch(SAMLException ex){
log.log(Level.SEVERE,
LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
throw new WSTrustException(LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
}catch(XWSSecurityException ex){
log.log(Level.SEVERE,
LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
throw new WSTrustException(LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
}
return assertion;
}
private Assertion createSAML20Assertion(final String assertionId, final String issuer, final String appliesTo, final KeyInfo keyInfo, final Map> claimedAttrs) throws WSTrustException{
Assertion assertion = null;
try{
final SAMLAssertionFactory samlFac = SAMLAssertionFactory.newInstance(SAMLAssertionFactory.SAML2_0);
// Create Conditions
final GregorianCalendar issueInst = new GregorianCalendar();
final GregorianCalendar notOnOrAfter = new GregorianCalendar();
notOnOrAfter.add(Calendar.MILLISECOND, (int)stsConfig.getIssuedTokenTimeout());
final Conditions conditions = samlFac.createConditions(issueInst, notOnOrAfter, null, null, null, null);
// Create Subject
final SubjectConfirmationData subjComfData = samlFac.createSubjectConfirmationData(
null, null, issueInst, notOnOrAfter, appliesTo, keyInfo);
final SubjectConfirmation subConfirmation = samlFac.createSubjectConfirmation(
null, subjComfData, SAML_HOLDER_OF_KEY);
com.sun.xml.wss.saml.Subject subj = null;
final List attrs = new ArrayList();
final Set>> entries = claimedAttrs.entrySet();
for(Map.Entry> entry : entries){
final QName attrKey = (QName)entry.getKey();
final List values = (List)entry.getValue();
if (values != null && values.size() > 0){
if (STSAttributeProvider.NAME_IDENTIFIER.equals(attrKey.getLocalPart()) && subj == null){
final NameIdentifier nameId = samlFac.createNameIdentifier(values.get(0), attrKey.getNamespaceURI(), null);
subj = samlFac.createSubject(nameId, subConfirmation);
}
else{
final Attribute attr = samlFac.createAttribute(attrKey.getLocalPart(), values);
attrs.add(attr);
}
}
}
final AttributeStatement statement = samlFac.createAttributeStatement(attrs);
final List statements = new ArrayList();
statements.add(statement);
final NameID issuerID = samlFac.createNameID(issuer, null, null);
// Create Assertion
assertion =
samlFac.createAssertion(assertionId, issuerID, issueInst, conditions, null, subj, statements);
}catch(SAMLException ex){
log.log(Level.SEVERE,
LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
throw new WSTrustException(LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
}catch(XWSSecurityException ex){
log.log(Level.SEVERE,
LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
throw new WSTrustException(LogStringsMessages.WST_0032_ERROR_CREATING_SAML_ASSERTION(), ex);
}
return assertion;
}
private KeyInfo createKeyInfo(final String keyType, final X509Certificate serCert, final IssuedTokenContext ctx)throws WSTrustException{
final KeyInfo keyInfo = new KeyInfo();
if (WSTrustConstants.SYMMETRIC_KEY.equals(keyType)){
final byte[] key = ctx.getProofKey();
if (!stsConfig.getEncryptIssuedToken() && stsConfig.getEncryptIssuedKey()){
try{
final Key secKey = new SecretKeySpec(key, "AES");
final EncryptedKey encKey = encryptKey(secKey, serCert);
keyInfo.getContent().add(encKey);
}catch(Exception ex){
throw new WSTrustException(ex.getMessage(), ex);
}
}else{
final BinarySecret secret = eleFac.createBinarySecret(key, wstVer.getSymmetricKeyTypeURI());
keyInfo.getContent().add(secret);
}
}else if(WSTrustConstants.PUBLIC_KEY.equals(keyType)){
final X509Data x509Data = new X509Data();
final Set certs = ctx.getRequestorSubject().getPublicCredentials();
if(certs == null){
log.log(Level.SEVERE,
LogStringsMessages.WST_0034_UNABLE_GET_CLIENT_CERT());
throw new WSTrustException(LogStringsMessages.WST_0034_UNABLE_GET_CLIENT_CERT());
}
boolean addedClientCert = false;
final ObjectFactory dsigOF = new ObjectFactory();
for(Object o : certs){
if(o instanceof X509Certificate){
final X509Certificate clientCert = (X509Certificate)o;
JAXBElement certElement;
try {
certElement = dsigOF.createX509DataTypeX509Certificate(clientCert.getEncoded());
} catch (CertificateEncodingException ex) {
//ex.printStackTrace();
throw new WSTrustException("Unable to create KeyInfo",ex);
}
@SuppressWarnings("unchecked") final List