DateTime expirationTime, RahasData data) throws Exception {
// TODO modify these to use proper SAML apis
XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
SAMLObjectBuilder<Subject> subjectBuilder =
(SAMLObjectBuilder<Subject>) builderFactory.getBuilder(Subject.DEFAULT_ELEMENT_NAME);
Subject subject = subjectBuilder.buildObject();
Element keyInfoElem = null;
// If it is a Symmetric Key
if (data.getKeyType().endsWith(RahasConstants.KEY_TYPE_SYMM_KEY)) {
isSymmetricKeyBasedHoK = true;
Element encryptedKeyElem;
X509Certificate serviceCert = null;
try {
// Get ApliesTo to figure out which service to issue the token
// for
serviceCert = config.getServiceCert(crypto, data.getAppliesToAddress());
// Create the encrypted key
WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();
// Use thumbprint id
encrKeyBuilder
.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
// SEt the encryption cert
encrKeyBuilder.setUseThisCert(serviceCert);
// set keysize
int keysize = data.getKeysize();
keysize = (keysize != -1) ? keysize : config.keySize;
// TODO setting keysize is removed with wss4j 1.6 migration - do we actually need this ?
encrKeyBuilder.setEphemeralKey(TokenIssuerUtil.getSharedSecret(
data, config.keyComputation, keysize));
// Set key encryption algo
encrKeyBuilder
.setKeyEncAlgo(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
// Build
encrKeyBuilder.prepare(doc, crypto);
// Extract the base64 encoded secret value
byte[] tempKey = new byte[keysize / 8];
System.arraycopy(encrKeyBuilder.getEphemeralKey(), 0, tempKey,
0, keysize / 8);
data.setEphmeralKey(tempKey);
// Extract the Encryptedkey DOM element
encryptedKeyElem = encrKeyBuilder.getEncryptedKeyElement();
} catch (WSSecurityException e) {
throw new TrustException(
"errorInBuildingTheEncryptedKeyForPrincipal",
new String[]{serviceCert.getSubjectDN().getName()},
e);
}
keyInfoElem = doc.createElementNS(WSConstants.SIG_NS,
"ds:KeyInfo");
((OMElement) encryptedKeyElem).declareNamespace(WSConstants.SIG_NS,
WSConstants.SIG_PREFIX);
((OMElement) encryptedKeyElem).declareNamespace(WSConstants.ENC_NS,
WSConstants.ENC_PREFIX);
keyInfoElem.appendChild(encryptedKeyElem);
}
// If it is a public Key
else if(data.getKeyType().endsWith(RahasConstants.KEY_TYPE_PUBLIC_KEY)){
try {
String subjectNameId = data.getPrincipal().getName();
//Create NameID and attach it to the subject
NameIDBuilder nb = new NameIDBuilder();
NameID nameID = nb.buildObject();
nameID.setValue(subjectNameId);
nameID.setFormat(NameIdentifier.EMAIL);
subject.setNameID(nameID);
// Create the ds:KeyValue element with the ds:X509Data
X509Certificate clientCert = data.getClientCert();
if (clientCert == null) {
// TODO are we always looking up by alias ? Dont we need to lookup by any other attribute ?
clientCert = CommonUtil.getCertificateByAlias(crypto, data.getPrincipal().getName());
}
byte[] clientCertBytes = clientCert.getEncoded();
String base64Cert = Base64.encode(clientCertBytes);
Text base64CertText = doc.createTextNode(base64Cert);
//-----------------------------------------
Element x509CertElem = doc.createElementNS(WSConstants.SIG_NS,
"ds:X509Certificate");
x509CertElem.appendChild(base64CertText);
Element x509DataElem = doc.createElementNS(WSConstants.SIG_NS,
"ds:X509Data");
x509DataElem.appendChild(x509CertElem);
if (x509DataElem != null) {
keyInfoElem = doc.createElementNS(WSConstants.SIG_NS, "ds:KeyInfo");
((OMElement) x509DataElem).declareNamespace(
WSConstants.SIG_NS, WSConstants.SIG_PREFIX);
keyInfoElem.appendChild(x509DataElem);
}
} catch (Exception e) {
throw new TrustException("samlAssertionCreationError", e);
}
}
// Unmarshall the keyInfo DOM element into an XMLObject
String keyInfoElementString = keyInfoElem.toString();
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(new ByteArrayInputStream(keyInfoElementString.trim().getBytes()));
Element element = document.getDocumentElement();
// Get appropriate unmarshaller
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
// Unmarshall using the document root element, an keyInfo element in this case
XMLObject keyInfoElement = null;
try {
keyInfoElement = unmarshaller.unmarshall(element);
} catch (UnmarshallingException e) {
throw new TrustException("Error unmarshalling KeyInfo Element", e);
}
//Build the Subject Confirmation
SAMLObjectBuilder<SubjectConfirmation> subjectConfirmationBuilder =
(SAMLObjectBuilder<SubjectConfirmation>) builderFactory.getBuilder(SubjectConfirmation.DEFAULT_ELEMENT_NAME);
SubjectConfirmation subjectConfirmation = subjectConfirmationBuilder.buildObject();
//Set the subject Confirmation method
subjectConfirmation.setMethod("urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
SAMLObjectBuilder<KeyInfoConfirmationDataType> keyInfoSubjectConfirmationDataBuilder =
(SAMLObjectBuilder<KeyInfoConfirmationDataType>) builderFactory.getBuilder(KeyInfoConfirmationDataType.TYPE_NAME);
//Build the subject confirmation data element
KeyInfoConfirmationDataType scData = keyInfoSubjectConfirmationDataBuilder.
buildObject(SubjectConfirmationData.DEFAULT_ELEMENT_NAME, KeyInfoConfirmationDataType.TYPE_NAME);