| /* |
| * Copyright 2004,2005 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.rahas.impl; |
| |
| import java.security.SecureRandom; |
| |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.om.util.Base64; |
| import org.apache.rahas.RahasConstants; |
| import org.apache.rahas.RahasData; |
| import org.apache.rahas.Token; |
| import org.apache.rahas.TrustException; |
| import org.apache.rahas.TrustUtil; |
| import org.apache.ws.security.WSConstants; |
| import org.apache.ws.security.WSSecurityException; |
| import org.apache.ws.security.components.crypto.Crypto; |
| import org.apache.ws.security.components.crypto.CryptoFactory; |
| import org.apache.ws.security.conversation.ConversationException; |
| import org.apache.ws.security.conversation.dkalgo.P_SHA1; |
| import org.apache.ws.security.message.WSSecEncryptedKey; |
| import org.apache.ws.security.util.WSSecurityUtil; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| /** |
| * |
| */ |
| public class TokenIssuerUtil { |
| |
| public final static String ENCRYPTED_KEY = "EncryptedKey"; |
| public final static String BINARY_SECRET = "BinarySecret"; |
| |
| public static byte[] getSharedSecret(RahasData data, |
| int keyComputation, |
| int keySize) throws TrustException { |
| |
| boolean reqEntrPresent = data.getRequestEntropy() != null; |
| |
| try { |
| if (reqEntrPresent && |
| keyComputation != SAMLTokenIssuerConfig.KeyComputation.KEY_COMP_USE_OWN_KEY) { |
| //If there is requester entropy and if the issuer is not |
| //configured to use its own key |
| |
| if (keyComputation == |
| SAMLTokenIssuerConfig.KeyComputation.KEY_COMP_PROVIDE_ENT) { |
| data.setResponseEntropy(WSSecurityUtil.generateNonce(keySize / 8)); |
| P_SHA1 p_sha1 = new P_SHA1(); |
| return p_sha1.createKey(data.getRequestEntropy(), |
| data.getResponseEntropy(), |
| 0, |
| keySize / 8); |
| } else { |
| //If we reach this its expected to use the requestor's |
| //entropy |
| return data.getRequestEntropy(); |
| } |
| } else { // need to use a generated key |
| return generateEphemeralKey(keySize); |
| } |
| } catch (WSSecurityException e) { |
| throw new TrustException("errorCreatingSymmKey", e); |
| } catch (ConversationException e) { |
| throw new TrustException("errorCreatingSymmKey", e); |
| } |
| } |
| |
| public static void handleRequestedProofToken(RahasData data, |
| int wstVersion, |
| AbstractIssuerConfig config, |
| OMElement rstrElem, |
| Token token, |
| Document doc) throws TrustException { |
| OMElement reqProofTokElem = |
| TrustUtil.createRequestedProofTokenElement(wstVersion, rstrElem); |
| |
| if (config.keyComputation == AbstractIssuerConfig.KeyComputation.KEY_COMP_PROVIDE_ENT |
| && data.getRequestEntropy() != null) { |
| //If we there's requester entropy and its configured to provide |
| //entropy then we have to set the entropy value and |
| //set the RPT to include a ComputedKey element |
| |
| OMElement respEntrElem = TrustUtil.createEntropyElement(wstVersion, rstrElem); |
| String entr = Base64.encode(data.getResponseEntropy()); |
| OMElement binSecElem = TrustUtil.createBinarySecretElement(wstVersion, |
| respEntrElem, |
| RahasConstants.BIN_SEC_TYPE_NONCE); |
| binSecElem.setText(entr); |
| |
| OMElement compKeyElem = |
| TrustUtil.createComputedKeyElement(wstVersion, reqProofTokElem); |
| compKeyElem.setText(data.getWstNs() + RahasConstants.COMPUTED_KEY_PSHA1); |
| } else { |
| if (TokenIssuerUtil.ENCRYPTED_KEY.equals(config.proofKeyType)) { |
| WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey(); |
| Crypto crypto; |
| if (config.cryptoElement != null) { // crypto props defined as elements |
| crypto = CryptoFactory.getInstance(TrustUtil.toProperties(config.cryptoElement), |
| data.getInMessageContext(). |
| getAxisService().getClassLoader()); |
| } else { // crypto props defined in a properties file |
| crypto = CryptoFactory.getInstance(config.cryptoPropertiesFile, |
| data.getInMessageContext(). |
| getAxisService().getClassLoader()); |
| } |
| |
| encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER); |
| try { |
| encrKeyBuilder.setUseThisCert(data.getClientCert()); |
| encrKeyBuilder.prepare(doc, crypto); |
| } catch (WSSecurityException e) { |
| throw new TrustException("errorInBuildingTheEncryptedKeyForPrincipal", |
| new String[]{data. |
| getClientCert().getSubjectDN().getName()}); |
| } |
| Element encryptedKeyElem = encrKeyBuilder.getEncryptedKeyElement(); |
| Element bstElem = encrKeyBuilder.getBinarySecurityTokenElement(); |
| if (bstElem != null) { |
| reqProofTokElem.addChild((OMElement) bstElem); |
| } |
| |
| reqProofTokElem.addChild((OMElement) encryptedKeyElem); |
| |
| token.setSecret(encrKeyBuilder.getEphemeralKey()); |
| } else if (TokenIssuerUtil.BINARY_SECRET.equals(config.proofKeyType)) { |
| byte[] secret = TokenIssuerUtil.getSharedSecret(data, |
| config.keyComputation, |
| config.keySize); |
| OMElement binSecElem = TrustUtil.createBinarySecretElement(wstVersion, |
| reqProofTokElem, |
| null); |
| binSecElem.setText(Base64.encode(secret)); |
| token.setSecret(secret); |
| } else { |
| throw new IllegalArgumentException(config.proofKeyType); |
| } |
| } |
| } |
| |
| private static byte[] generateEphemeralKey(int keySize) throws TrustException { |
| try { |
| SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); |
| byte[] temp = new byte[keySize / 8]; |
| random.nextBytes(temp); |
| return temp; |
| } catch (Exception e) { |
| throw new TrustException("errorCreatingSymmKey", e); |
| } |
| } |
| |
| } |