Author: dimuthul
Date: Thu Feb 21 06:28:46 2008
New Revision: 13999
Log:
Adding token issuer with my local changes.
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/IssuerCertificateUtil.java
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenConsumer.java
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenVerifier.java
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialImpl.java
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialUtil.java
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML1TokenHolder.java
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML2TokenHolder.java
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/TokenHolder.java
Modified:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties
Modified:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties
==============================================================================
---
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties
(original)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/resources.properties
Thu Feb 21 06:28:46 2008
@@ -1,3 +1,4 @@
+errorReadingFromKeyInfo = Error reading key info from message : {0} : {1}
credentialIsNull = Cannot find the key to validate Signature.
signingCertNull = Signing certificate cannot be null of whitelist, blacklist
and cert-validity
errorValidatingIssuerPolicy = Error validating issuer policy
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/IssuerCertificateUtil.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/IssuerCertificateUtil.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,132 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.ws.security.components.crypto.X509NameTokenizer;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+
+public class IssuerCertificateUtil {
+
+ /**
+ * This method checks whether the certificate is present in the
certificate store
+ */
+ public static boolean checkSystemStoree(X509Certificate signedCert,
+ KeyStore trustStore, KeyStore systemStore) throws Exception {
+
+ boolean isCertValid = false;
+
+ String certIssuerName = signedCert.getIssuerDN().getName();
+
+ // validity period
+ signedCert.checkValidity();
+
+ // is Trusted? checking in System store.
+ try {
+ isCertValid = systemStore.containsAlias(certIssuerName);
+ } catch (Exception e) {
+ throw new RelyingPartyException("errorLoadingTrustedKeystore", e);
+ }
+
+ return isCertValid;
+
+ }
+
+ /**
+ * Performs the black list check
+ * @param blackList Array of Lists. One Array element contains the
Issuer's cert DN
+ * @param cert
+ * @return
+ * @throws RelyingPartyException
+ */
+ public static boolean doBlackListCheck(List[] blackList,
+ X509Certificate cert) throws RelyingPartyException {
+ boolean isGreenLight = true;
+
+ if (cert == null) {
+ throw new RelyingPartyException("noCertInToken");
+ }
+
+ if (blackList == null) {
+ isGreenLight = true;
+ } else {
+ String value = cert.getIssuerDN().getName();
+ List certDN = getDNOfIssuer(value);
+ for (int i = 0; i < blackList.length; i++) {
+ List issuerDN = blackList[i];
+ if (certDN.equals(issuerDN)) {
+ isGreenLight = false;
+ break;
+ }
+ }
+ }
+
+ return isGreenLight;
+ }
+
+ /**
+ * Do a white list check
+ *
+ * @param whiteList Array of Lists. One Array element contains the
Issuer's cert DN
+ * @param cert
+ * @return
+ * @throws RelyingPartyException
+ */
+ public static boolean doWhiteListCheck(List[] whiteList,
+ X509Certificate cert) throws RelyingPartyException {
+ boolean isGreenLight = false;
+
+ if (cert == null) {
+ throw new RelyingPartyException("noCertInToken");
+ }
+ if (whiteList != null) {
+ String inString = cert.getIssuerDN().getName();
+ List certDN = getDNOfIssuer(inString);
+ for (int i = 0; i < whiteList.length; i++) {
+ List issuerDN = whiteList[i];
+ if (certDN.equals(issuerDN)) {
+ isGreenLight = true;
+ break;
+ }
+ }
+ }
+ return isGreenLight;
+ }
+
+ /**
+ * Retrieves the CN of the subject of the given Certificate
+ * @param cert
+ * @return
+ */
+ public static String getCNOfSubject(X509Certificate cert) {
+ String dn = cert.getIssuerDN().getName();
+ if (dn.contains("CN=")) {
+ int beginIndex = dn.indexOf("CN=");
+ int endIndex = dn.indexOf(",", beginIndex);
+ String name = dn.substring(beginIndex + 3, endIndex).trim();
+ return name;
+ }
+ return null;
+ }
+
+ /**
+ * Retrieves the DN Of Issuer
+ * @param inString
+ * @return
+ */
+ public static List getDNOfIssuer(String inString) {
+
+ X509NameTokenizer nmTokens = new X509NameTokenizer(inString);
+ List lst = new ArrayList();
+
+ while (nmTokens.hasMoreTokens()) {
+ lst.add(nmTokens.nextToken());
+ }
+ Collections.sort(lst);
+ return lst;
+ }
+
+}
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenConsumer.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenConsumer.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,234 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.io.StringReader;
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.Base64;
+import org.apache.ws.security.util.DOM2Writer;
+import org.opensaml.DefaultBootstrap;
+import org.opensaml.xml.ConfigurationException;
+import org.w3c.dom.Element;
+import org.wso2.solutions.identity.IdentityConstants;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+import org.wso2.solutions.identity.relyingparty.TokenVerifierConstants;
+import org.wso2.solutions.identity.relyingparty.servletfilter.RelyingPartyData;
+
+public class SAMLTokenConsumer {
+
+ private static SAMLTokenConsumer consumer = null;
+
+ static {
+ try {
+ DefaultBootstrap.bootstrap();
+ } catch (ConfigurationException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ private SAMLTokenConsumer() {
+
+ }
+
+ /**
+ * Returns the SAMLTokenConsuer
+ *
+ * @return
+ */
+ public static SAMLTokenConsumer getInstance() {
+ if (consumer == null) {
+ consumer = new SAMLTokenConsumer();
+ }
+ return consumer;
+ }
+
+ /**
+ * The control flow is 1) Verify 2) Validate policies 3) Inject parameters
+ * into the HttpServletRequest
+ *
+ * @param request
+ * @param xmlToken
+ * @param data
+ * @throws RelyingPartyException
+ */
+ public void setInfocardSessionAttributes(HttpServletRequest request,
+ String xmlToken, RelyingPartyData data)
+ throws RelyingPartyException {
+ SAMLTokenVerifier verifier = new SAMLTokenVerifier();
+
+ Element plainTokenElem = verifier.decryptToken(xmlToken, data
+ .getPrivateKey());
+
+ boolean isAllSuccess = false;
+
+ if (verifier.verifyDecryptedToken(plainTokenElem, data)) {
+ if (validateIssuerInfoPolicy(verifier, data)) {
+ isAllSuccess = true;
+ }
+ }
+
+ if (isAllSuccess == false) {
+ injectDataToRequestOnFailure(verifier, request);
+ } else {
+ injectDataToRequestOnSuccess(verifier, request);
+ }
+
+ }
+
+ /**
+ * Validates issuer info
+ *
+ * @param verifier
+ * @return Whether issue validation successful or not.
+ * @throws Exception
+ */
+ protected boolean validateIssuerInfoPolicy(SAMLTokenVerifier verifier,
+ RelyingPartyData data) throws RelyingPartyException {
+ boolean validated = false;
+ String issuerName = verifier.getIssuerName();
+ String issuerPolicy = data.getIssuerPolicy();
+ String validatePolicy = data.getValidatePolicy();
+
+ try {
+ if (IdentityConstants.SELF_ISSUED_ISSUER.equals(issuerName)) {
+
+ if (issuerPolicy == null
+ || issuerPolicy
+ .equals(TokenVerifierConstants.SELF_ONLY)
+ || issuerPolicy
+
.equals(TokenVerifierConstants.SELF_AND_MANGED)) {
+ validated = true;
+ }
+ } else if (issuerPolicy.equals(TokenVerifierConstants.SELF_ONLY)) {
+ // not a self issued card when self only
+ validated = false;
+ } else {
+ validated = true;
+ }
+ } catch (Exception e) {
+ throw new RelyingPartyException("errorValidatingIssuerPolicy", e);
+ }
+
+ return validated;
+ }
+
+ /**
+ * When the data token is invalid, this method injects invalid status
+ * message.
+ *
+ * @param verifier
+ * @param request
+ */
+ protected void injectDataToRequestOnFailure(SAMLTokenVerifier verifier,
+ ServletRequest request) {
+
+ request.setAttribute(TokenVerifierConstants.SERVLET_ATTR_STATE,
+ TokenVerifierConstants.STATE_FAILURE);
+ }
+
+ /**
+ * When the token is valid this method injects valid states message
+ *
+ * @param verifier
+ * @param request
+ * @throws RelyingPartyException
+ */
+ protected void injectDataToRequestOnSuccess(SAMLTokenVerifier verifier,
+ ServletRequest request) throws RelyingPartyException {
+
+ request.setAttribute(TokenVerifierConstants.SERVLET_ATTR_STATE,
+ TokenVerifierConstants.STATE_SUCCESS);
+
+ String issuerInfo = getIssuerInfoString(verifier);
+ if (issuerInfo != null) {
+ request
+ .setAttribute(TokenVerifierConstants.ISSUER_INFO,
+ issuerInfo);
+ }
+
+ Iterator propertyEntry = verifier.getAttributeTable().entrySet()
+ .iterator();
+ while (propertyEntry.hasNext()) {
+ Entry entry = (Entry) propertyEntry.next();
+ String key = (String) entry.getKey();
+ String value = (String) entry.getValue();
+ request.setAttribute(key, value);
+ }
+
+ }
+
+ protected String getIssuerInfoString(SAMLTokenVerifier verifier)
+ throws RelyingPartyException {
+ String issuerInfo = null;
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ OMNamespace ns = factory.createOMNamespace(TokenVerifierConstants.NS,
+ TokenVerifierConstants.PREFIX);
+
+ List certficates = verifier.getCertificates();
+ Element keyInfo = verifier.getKeyInfoElement();
+ OMElement certificates;
+ OMElement omKeyInfo;
+ try {
+ Iterator ite = certficates.iterator();
+ boolean siginingSet = false;
+ certificates = null;
+ OMElement certElem = null;
+ while (ite.hasNext()) {
+ X509Certificate cert = (X509Certificate) ite.next();
+ byte[] encodedCert = cert.getEncoded();
+ String base64Encoded = Base64.encode(encodedCert);
+ if (certificates == null) {
+ certificates = factory.createOMElement(
+ TokenVerifierConstants.LN_CERTIFICATES, ns);
+ }
+
+ certElem = factory.createOMElement(
+ TokenVerifierConstants.LN_CERTIFICATE, ns);
+ if (siginingSet == false) {
+ certElem.addAttribute(
+ TokenVerifierConstants.LN_SIGNING_CERT, "true",
+ null);
+ siginingSet = true;
+ }
+ certElem.setText(base64Encoded);
+ certificates.addChild(certElem);
+ }
+
+ omKeyInfo = null;
+ if (keyInfo != null) {
+ String value = DOM2Writer.nodeToString(keyInfo);
+ XMLStreamReader parser = XMLInputFactory.newInstance()
+ .createXMLStreamReader(new StringReader(value));
+ StAXOMBuilder builder = new StAXOMBuilder(parser);
+ omKeyInfo = builder.getDocumentElement();
+
+ }
+ } catch (Exception e) {
+ throw new RelyingPartyException("errorBuildingIssuerInfo");
+ }
+
+ if (certificates != null) {
+ issuerInfo = certificates.toString();
+ }
+
+ if (omKeyInfo != null) {
+ issuerInfo = issuerInfo + omKeyInfo.toString();
+ }
+
+ return issuerInfo;
+ }
+
+}
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenVerifier.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/SAMLTokenVerifier.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2005-2007 WSO2, Inc. (http://wso2.com)
+ *
+ * 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.wso2.solutions.identity.relyingparty.saml;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URI;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.crypto.SecretKey;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.processor.EncryptedKeyProcessor;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.Init;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.utils.EncryptionConstants;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureValidator;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.wso2.solutions.identity.IdentityConstants;
+import org.wso2.solutions.identity.i18n.Messages;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+import org.wso2.solutions.identity.relyingparty.TokenVerifierConstants;
+import org.wso2.solutions.identity.relyingparty.saml.tokens.SAML1TokenHolder;
+import org.wso2.solutions.identity.relyingparty.saml.tokens.SAML2TokenHolder;
+import org.wso2.solutions.identity.relyingparty.saml.tokens.TokenHolder;
+import org.wso2.solutions.identity.relyingparty.servletfilter.RelyingPartyData;
+
+/**
+ * A SAML token is sent to a web application in a CardSpace login attempt and
+ * this can be used for decryption and verification of those tokens.
+ */
+public class SAMLTokenVerifier {
+
+ private static Log log = LogFactory.getLog(SAMLTokenVerifier.class);
+
+ private static Messages messages = Messages
+ .getInstance(TokenVerifierConstants.RESOURCES);
+
+ private Hashtable attributeTable = new Hashtable();
+
+ private List certificates = new ArrayList();
+
+ private Element keyInfoElement = null;
+
+ private String issuerName = null;
+
+ private boolean isMultipleValues = false;
+
+ private X509Certificate signingCert = null;
+
+ static {
+ Init.init();
+ }
+
+ /**
+ * Decrypt the given token (as a <code>java.lang.String</code> with the
+ * given private key.
+ *
+ * @param token
+ * Serialized SAML token
+ * @param serviceKey
+ * Private key to be used for decryption.
+ * @return Decrypted SAML token element.
+ * @throws RelyingPartyException
+ */
+ public Element decryptToken(String token, PrivateKey serviceKey)
+ throws RelyingPartyException {
+
+ try {
+
+ if (log.isDebugEnabled()) {
+ log.debug(messages.getMessage("receivedEncryuptedToken",
+ new String[] { token }));
+ }
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(token
+ .getBytes());
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ Document doc = dbf.newDocumentBuilder().parse(bais);
+ Element encryptedTokenElem = doc.getDocumentElement();
+
+ // Decrypt element
+ return this.decryptElement(serviceKey, encryptedTokenElem);
+
+ } catch (Exception e) {
+ throw new RelyingPartyException("verificationFailure", e);
+ }
+
+ }
+
+ /**
+ * This method performs two actions 1) Decrypt the token 2) Verify the
token
+ *
+ * @param decryptedElem
+ * SAML token element
+ * @return true if verification is successful and false if unsuccessful.
+ * @throws SAMLException
+ */
+ public boolean verifyDecryptedToken(Element decryptedElem,
+ RelyingPartyData rpData) throws RelyingPartyException {
+
+ boolean isValid = true;
+ if (log.isDebugEnabled()) {
+ log.debug(messages.getMessage("verifyingDecryptedToken"));
+ }
+
+ if (log.isDebugEnabled()) {
+ try {
+ String val = DOM2Writer.nodeToString(decryptedElem);
+ log.debug(val);
+ FileWriter writer = new FileWriter(new File("last_msg.xml"));
+ writer.write(val.toCharArray());
+ writer.flush();
+ writer.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ try {
+
+ String version = decryptedElem.getNamespaceURI();
+ TokenHolder holder = null;
+ if (version.equals(IdentityConstants.SAML10_URL)
+ || version.equals(IdentityConstants.SAML11_URL)) {
+ holder = new SAML1TokenHolder();
+ } else if (version.equals(IdentityConstants.SAML20_URL)) {
+ holder = new SAML2TokenHolder();
+ }
+
+ holder.createToken(decryptedElem);
+ issuerName = holder.getIssuerName();
+ if (issuerName == null) {
+ throw new RelyingPartyException("issuerIsNull");
+ }
+
+ Signature sig = holder.getSAMLSignature();
+ X509CredentialImpl credential = null;
+
+ if (issuerName.equals(IdentityConstants.SELF_ISSUED_ISSUER)) {
+ credential = (X509CredentialImpl) X509CredentialUtil
+ .loadCredentialFromSignature(sig);
+ this.keyInfoElement = sig.getKeyInfo().getDOM();
+ } else {
+
+ String alias = null;
+ URI uri = new URI(issuerName);
+ alias = uri.getHost();
+
+ KeyStore trustStore = rpData.getTrustStore();
+ KeyStore systemStore = rpData.getSystemStore();
+
+ credential = (X509CredentialImpl) X509CredentialUtil
+ .loadCredentialFromTrustStore(alias, trustStore);
+
+ String validationPolicy = rpData.getValidatePolicy();
+
+ boolean isLoadedFromMessage = false;
+ if (credential == null) {
+ credential = (X509CredentialImpl) X509CredentialUtil
+ .loadCredentialFromSignature(sig);
+
+ if (credential == null)
+ throw new RelyingPartyException("credentialIsNull");
+
+ isLoadedFromMessage = true;
+ }
+
+ this.signingCert = credential.getSigningCert();
+
+ if (!validationPolicy
+ .equals(TokenVerifierConstants.PROMISCUOUS)) {
+
+ if (signingCert == null)
+ throw new RelyingPartyException("signingCertNull");
+
+ /*
+ * do certificate validation for blacklist, whitelist and
+ * cert-validity
+ */
+
+ signingCert.checkValidity();
+
+ if (isLoadedFromMessage) {
+ if (!IssuerCertificateUtil.checkSystemStoree(
+ signingCert, trustStore, systemStore)) {
+ isValid = false;
+ }
+ }
+
+ if (validationPolicy
+ .equals(TokenVerifierConstants.BLACK_LIST)) {
+ if (!IssuerCertificateUtil.doBlackListCheck(rpData
+ .getBlackList(), signingCert)) {
+ isValid = false;
+ }
+ }
+
+ if (validationPolicy
+ .equals(TokenVerifierConstants.WHITE_LIST)) {
+ if (!IssuerCertificateUtil.doWhiteListCheck(rpData
+ .getWhiteList(), signingCert)) {
+ isValid = false;
+ }
+ }
+ }
+ }
+
+ if (isValid) {
+ SignatureValidator validator = new SignatureValidator(
+ credential);
+ validator.validate(sig);
+ holder.populateAttributeTable(this.attributeTable);
+ }
+
+ } catch (Exception e) {
+ log.debug(e);
+ throw new RelyingPartyException("errorInTokenVerification",
+ new Object[] { e.getMessage() });
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug(messages.getMessage("verifyingDecryptedTokenDone"));
+ }
+
+ // everything is fine :D
+ return isValid;
+ }
+
+ private Element decryptElement(PrivateKey privKey, Element encryptedToken)
+ throws Exception {
+
+ if (log.isDebugEnabled()) {
+ log.debug(messages.getMessage("decryptingToken"));
+ }
+
+ Element kiElem = (Element) encryptedToken.getElementsByTagNameNS(
+ WSConstants.SIG_NS, "KeyInfo").item(0);
+ Element encrKeyElem = (Element) kiElem.getElementsByTagNameNS(
+ WSConstants.ENC_NS, EncryptionConstants._TAG_ENCRYPTEDKEY)
+ .item(0);
+
+ EncryptedKeyProcessor encrKeyProcessor = new EncryptedKeyProcessor();
+ encrKeyProcessor.handleEncryptedKey(encrKeyElem, privKey);
+
+ SecretKey secretKey = WSSecurityUtil.prepareSecretKey(
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
+ encrKeyProcessor.getDecryptedBytes());
+
+ XMLCipher cipher = XMLCipher.getInstance();
+ cipher.init(XMLCipher.DECRYPT_MODE, secretKey);
+
+ Document doc = cipher.doFinal(encryptedToken.getOwnerDocument(),
+ encryptedToken);
+ if (log.isDebugEnabled()) {
+ log.debug(messages.getMessage("decryptingTokenDone"));
+ }
+
+ return doc.getDocumentElement();
+ }
+
+ public X509Certificate getSigningCert() {
+ return signingCert;
+ }
+
+ /**
+ * Returns the list of attributes extracted from the
SAMLAttributeStatements
+ * in the verified SAML assertion.
+ *
+ * @return List of attributes as a <code>java.util.Hashtable</code>
+ */
+ public Hashtable getAttributeTable() {
+ return attributeTable;
+ }
+
+ public List getCertificates() {
+ return certificates;
+ }
+
+ public Element getKeyInfoElement() {
+ return keyInfoElement;
+ }
+
+ public String getIssuerName() {
+ return issuerName;
+ }
+
+ public void setIssuerName(String issuer) {
+ this.issuerName = issuer;
+ }
+
+ public boolean isMultipleValues() {
+ return isMultipleValues;
+ }
+
+ public void setMultipleValues(boolean isMultipleValues) {
+ this.isMultipleValues = isMultipleValues;
+ }
+
+}
\ No newline at end of file
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialImpl.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialImpl.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,113 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.Collection;
+
+import javax.crypto.SecretKey;
+
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.security.credential.CredentialContextSet;
+import org.opensaml.xml.security.credential.UsageType;
+import org.opensaml.xml.security.x509.X509Credential;
+
+/**
+ * X509Credential implementation for signature verification of self issued
tokens.
+ * The key is constructed from modulus and exponent
+ */
+public class X509CredentialImpl implements X509Credential {
+
+ private PublicKey publicKey = null;
+ private X509Certificate signingCert = null;
+
+ //cert chain
+
+ /**
+ * The key is constructed form modulus and exponent.
+ * @param modulus
+ * @param publicExponent
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ */
+ public X509CredentialImpl(BigInteger modulus, BigInteger publicExponent)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ publicKey = keyFactory.generatePublic(spec);
+ }
+
+ public X509CredentialImpl(X509Certificate cert) {
+ publicKey = cert.getPublicKey();
+ signingCert = cert;
+ }
+
+ /**
+ * Retrieves the publicKey
+ */
+ public PublicKey getPublicKey() {
+ return publicKey;
+ }
+
+ public X509Certificate getSigningCert() {
+ return signingCert;
+ }
+
+ // ********** Not implemented
**************************************************************
+ public X509Certificate getEntityCertificate() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Collection<X509CRL> getCRLs() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Collection<X509Certificate> getEntityCertificateChain() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public CredentialContextSet getCredentalContextSet() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Class<? extends Credential> getCredentialType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getEntityId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Collection<String> getKeyNames() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public PrivateKey getPrivateKey() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public SecretKey getSecretKey() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public UsageType getUsageType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialUtil.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/X509CredentialUtil.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,116 @@
+package org.wso2.solutions.identity.relyingparty.saml;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.CertificateFactory;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.xml.security.utils.Base64;
+import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.xml.signature.Exponent;
+import org.opensaml.xml.signature.KeyInfo;
+import org.opensaml.xml.signature.KeyValue;
+import org.opensaml.xml.signature.Modulus;
+import org.opensaml.xml.signature.RSAKeyValue;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.X509Certificate;
+import org.opensaml.xml.signature.X509Data;
+import org.w3c.dom.Element;
+import org.wso2.solutions.identity.relyingparty.RelyingPartyException;
+
+/**
+ * This class creates the X509CredentialImpl that is needed to
+ * verify the signature.
+ *
+ */
+public class X509CredentialUtil {
+
+ public static KeyStore systemKeyStore = null;
+
+ /**
+ * Creates the X509Credential from the TrustStore certificate.
+ */
+ public static X509Credential loadCredentialFromTrustStore(String alias,
+ KeyStore trustStore) throws RelyingPartyException {
+ X509Credential credential = null;
+ java.security.cert.X509Certificate cert = null;
+ try {
+ if (trustStore.containsAlias(alias)) {
+ cert = (java.security.cert.X509Certificate) trustStore
+ .getCertificate(alias);
+ credential = new X509CredentialImpl(cert);
+ }
+ } catch (KeyStoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return credential;
+ }
+
+ /**
+ * Creates the certificate from the KeyInfo element.
+ */
+ public static X509Credential loadCredentialFromSignature(Signature
signature)
+ throws RelyingPartyException {
+ X509Credential credential = null;
+ KeyInfo kinfo = signature.getKeyInfo();
+
+ if (kinfo == null) {
+ return null;
+ }
+
+ List<X509Data> dataList = kinfo.getX509Datas();
+ List<KeyValue> keyValueList = kinfo.getKeyValues();
+
+ try {
+ if (dataList.size() > 0) {
+ if (dataList.size() > 1) {
+ throw new RelyingPartyException("invalidKeyValueCount");
+ }
+ X509Data data = dataList.get(0);
+ List<X509Certificate> certList = data.getX509Certificates();
+ Iterator ite = certList.iterator();
+ while (ite.hasNext()) {
+ X509Certificate certElem = (X509Certificate) ite.next();
+ String certValue = certElem.getValue();
+ byte[] certInBytes = Base64.decode(certValue);
+ ByteArrayInputStream bis = new
ByteArrayInputStream(certInBytes);
+ CertificateFactory factory = CertificateFactory
+ .getInstance("X509");
+ java.security.cert.X509Certificate x509Cert =
(java.security.cert.X509Certificate) factory
+ .generateCertificate(bis);
+ credential = new X509CredentialImpl(x509Cert);
+ }
+ } else if (keyValueList.size() > 0) {
+ if (keyValueList.size() > 1) {
+ throw new RelyingPartyException("invalidKeyValueCount");
+ }
+
+ KeyValue val = (KeyValue) keyValueList.get(0);
+ RSAKeyValue rsaKey = val.getRSAKeyValue();
+
+ Element elem = rsaKey.getDOM();
+
+ Element modElem = (Element) elem.getElementsByTagName(
+ Modulus.DEFAULT_ELEMENT_LOCAL_NAME).item(0);
+ Element expElem = (Element) elem.getElementsByTagName(
+ Exponent.DEFAULT_ELEMENT_LOCAL_NAME).item(0);
+
+ BigInteger mod = Base64.decodeBigIntegerFromElement(modElem);
+ BigInteger exp = Base64.decodeBigIntegerFromElement(expElem);
+ credential = new X509CredentialImpl(mod, exp);
+ } else {
+ assert false : "unknown key info";
+ }
+ } catch (Exception e) {
+ throw new RelyingPartyException("errorReadingFromKeyInfo",
+ new Object[]{e.getClass(), e.getMessage()});
+ }
+
+ return credential;
+ }
+
+}
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML1TokenHolder.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML1TokenHolder.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,108 @@
+package org.wso2.solutions.identity.relyingparty.saml.tokens;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.opensaml.saml1.core.Assertion;
+import org.opensaml.saml1.core.Attribute;
+import org.opensaml.saml1.core.AttributeStatement;
+import org.opensaml.xml.Configuration;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.signature.Signature;
+import org.w3c.dom.Element;
+
+public class SAML1TokenHolder implements TokenHolder {
+
+ private Assertion assertion = null;
+
+ private boolean isMultipleValues = false;
+
+ private static Log log = LogFactory.getLog(SAML1TokenHolder.class);
+
+ /**
+ * Creates the SAML object from the element This method must be called
first
+ *
+ * @param elem
+ * @throws UnmarshallingException
+ * If the token creation fails
+ */
+ public void createToken(Element elem) throws UnmarshallingException {
+ UnmarshallerFactory unmarshallerFactory = Configuration
+ .getUnmarshallerFactory();
+ Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(elem);
+
+ assertion = (Assertion) unmarshaller.unmarshall(elem);
+ }
+
+ /**
+ * @return the SAML signature.
+ */
+ public Signature getSAMLSignature() {
+ return assertion.getSignature();
+ }
+
+ /**
+ * Issuer of the SAML token
+ *
+ * @return
+ */
+ public String getIssuerName() {
+ return assertion.getIssuer();
+ }
+
+ /**
+ * Populates the attributes.
+ *
+ * @param attributeTable
+ */
+ public void populateAttributeTable(Map attributeTable) {
+ Iterator statements = assertion.getAttributeStatements().iterator();
+ while (statements.hasNext()) {
+ AttributeStatement stmt = (AttributeStatement) statements.next();
+ Iterator attrs = stmt.getAttributes().iterator();
+ while (attrs.hasNext()) {
+ Attribute attr = (Attribute) attrs.next();
+ String name = attr.getAttributeNamespace() + "/"
+ + attr.getAttributeName();
+
+ List lst = attr.getAttributeValues();
+ Iterator ite = lst.iterator();
+ int count = 0;
+ StringBuffer buff = new StringBuffer();
+ while (ite.hasNext()) {
+ Object obj = ite.next();
+ if (obj instanceof XSString) {
+ buff.append(((XSString) obj).getValue());
+ } else if (obj instanceof XSAny) {
+ XSAny any = (XSAny) obj;
+ String value = any.getTextContent();
+ buff.append(value);
+ }
+ buff.append(",");
+ count++;
+ }
+
+ if (buff.length() > 1) {
+ buff.deleteCharAt(buff.length() - 1);
+ }
+
+ String value = buff.toString();
+
+ if (count > 1) {
+ isMultipleValues = true;
+ }
+
+ attributeTable.put(name, value);
+ }
+ }
+
+ }
+
+}
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML2TokenHolder.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/SAML2TokenHolder.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,109 @@
+package org.wso2.solutions.identity.relyingparty.saml.tokens;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeStatement;
+import org.opensaml.xml.Configuration;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.signature.Signature;
+import org.w3c.dom.Element;
+
+public class SAML2TokenHolder implements TokenHolder {
+
+ private Assertion assertion = null;
+
+ private boolean isMultipleValues = false;
+
+ private static Log log = LogFactory.getLog(SAML1TokenHolder.class);
+
+ /**
+ * Creates the SAML object from the element This method must be called
first
+ *
+ * @param elem
+ * @throws UnmarshallingException
+ * If the token creation fails
+ */
+ public void createToken(Element elem) throws UnmarshallingException {
+ UnmarshallerFactory unmarshallerFactory = Configuration
+ .getUnmarshallerFactory();
+ Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(elem);
+
+ assertion = (Assertion) unmarshaller.unmarshall(elem);
+ }
+
+ /**
+ * @return the SAML signature.
+ */
+ public Signature getSAMLSignature() {
+ return assertion.getSignature();
+ }
+
+ /**
+ * Issuer of the SAML token
+ *
+ * @return
+ */
+ public String getIssuerName() {
+ return assertion.getIssuer().getValue();
+ }
+
+ /**
+ * Populates the attributes.
+ *
+ * @param attributeTable
+ */
+ public void populateAttributeTable(Map attributeTable) {
+ Iterator statements = assertion.getAttributeStatements().iterator();
+ while (statements.hasNext()) {
+ AttributeStatement stmt = (AttributeStatement) statements.next();
+ Iterator attrs = stmt.getAttributes().iterator();
+ while (attrs.hasNext()) {
+ Attribute attr = (Attribute) attrs.next();
+ String attrNamesapce = attr.getNameFormat();
+ String attrName = attr.getName();
+ String name = attrNamesapce + "/" + attrName;
+
+ List lst = attr.getAttributeValues();
+ Iterator ite = lst.iterator();
+ int count = 0;
+ StringBuffer buff = new StringBuffer();
+ while (ite.hasNext()) {
+ Object obj = ite.next();
+ if (obj instanceof XSString) {
+ buff.append(((XSString) obj).getValue());
+ } else if (obj instanceof XSAny) {
+ XSAny any = (XSAny) obj;
+ String value = any.getTextContent();
+ buff.append(value);
+ }
+ buff.append(",");
+ count++;
+ }
+
+ if (buff.length() > 1) {
+ buff.deleteCharAt(buff.length() - 1);
+ }
+
+ String value = buff.toString();
+
+ if (count > 1) {
+ isMultipleValues = true;
+ }
+
+ attributeTable.put(name, value);
+ }
+ }
+
+ }
+
+}
Added:
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/TokenHolder.java
==============================================================================
--- (empty file)
+++
trunk/solutions/identity/modules/token-verifier-core/src/main/java/org/wso2/solutions/identity/relyingparty/saml/tokens/TokenHolder.java
Thu Feb 21 06:28:46 2008
@@ -0,0 +1,39 @@
+package org.wso2.solutions.identity.relyingparty.saml.tokens;
+
+import java.util.Map;
+
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.signature.Signature;
+import org.w3c.dom.Element;
+
+public interface TokenHolder {
+
+ /**
+ * Creates the SAML object from the element This method must be called
first
+ *
+ * @param elem
+ * @throws UnmarshallingException
+ * If the token creation fails
+ */
+ public void createToken(Element elem) throws UnmarshallingException;
+
+ /**
+ * @return the SAML signature.
+ */
+ public Signature getSAMLSignature();
+
+ /**
+ * Populates the attributes.
+ *
+ * @param attributeTable
+ */
+ public void populateAttributeTable(Map attributeTable);
+
+ /**
+ * Issuer of the SAML token
+ *
+ * @return
+ */
+ public String getIssuerName();
+
+}
_______________________________________________
Identity-dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/identity-dev