view flys-client/src/main/java/de/intevation/flys/client/server/auth/was/Signature.java @ 4488:5041105d2edd

Check if response code from GGInA is 200 OK Only parse the GGInA response if the status code is 200 OK. This improves the error message if GGInA is not available and shows the real reason instead of a JDOM error while parsing the response.
author Björn Ricks <bjoern.ricks@intevation.de>
date Wed, 14 Nov 2012 10:36:21 +0100
parents 725470fc57d2
children
line wrap: on
line source
package de.intevation.flys.client.server.auth.was;

import java.io.ByteArrayInputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.jdom.Element;

public class Signature {

    private static Logger logger = Logger.getLogger(Signature.class);

    private static final String XML_SIG_DIGEST_SHA1 =
        "http://www.w3.org/2000/09/xmldsig#sha1";
    private static final String XML_SIG_SIGNATURE_RSA_SHA1 =
        "http://www.w3.org/2000/09/xmldsig#rsa-sha1";

    private final Element signature;
    private Certificate cert;
    private byte[] value;
    private byte[] digestvalue;
    private String reference;

    public Signature(Element signature) {
        this.signature = signature;
        this.parseSignatureInfo();
        this.parseSignatureValue();
        this.parseCertificate();
    }

    private void parseSignatureInfo() {
        Element signatureinfo = this.signature.getChild("SignedInfo",
                Namespaces.XML_SIG_NS);
        if (signatureinfo != null) {
            Element signaturemethod = signatureinfo.getChild("SignatureMethod",
                    Namespaces.XML_SIG_NS);
            String algorithm = signaturemethod.getAttributeValue("Algorithm");
            if (!algorithm.equals(XML_SIG_SIGNATURE_RSA_SHA1)) {
                logger.warn("Unkown signature alorithm " + algorithm);
            }

            // There could be several references in XML-Sig spec but for me it
            // doesn't make sense to have more then one in a SAML Assertion
            Element reference = signatureinfo.getChild("Reference",
                    Namespaces.XML_SIG_NS);
            // reference must be present but its better to check
            if (reference != null) {
                String digestvalue = reference.getChildText("DigestValue",
                        Namespaces.XML_SIG_NS);
                String digestmethod = reference.getChildText("DigestMethod",
                        Namespaces.XML_SIG_NS);
                if (!digestmethod.equals(XML_SIG_DIGEST_SHA1)) {
                    logger.warn("Unknown digest method " + digestmethod);
                }
                this.digestvalue = Base64.decodeBase64(digestvalue);

                String referenceuri = reference.getAttributeValue("URI");
                if (referenceuri.startsWith("#")) {
                    this.reference = referenceuri.substring(1);
                }
                else {
                    logger.warn("Unkown reference type " + referenceuri);
                    this.reference = referenceuri;
                }
            }
        }
    }

    private void parseSignatureValue() {
        String signaturevalue = this.signature.getChildText("SignatureValue",
                Namespaces.XML_SIG_NS);
        this.value = Base64.decodeBase64(signaturevalue);
    }

    private void parseCertificate() {
        Element keyinfo = this.signature.getChild("KeyInfo",
                Namespaces.XML_SIG_NS);
        if (keyinfo != null) {
            Element data = keyinfo.getChild("X509Data", Namespaces.XML_SIG_NS);
            if (data != null) {
                String base64cert = data.getChildText("X509Certificate",
                        Namespaces.XML_SIG_NS);
                if (base64cert != null) {
                    byte[] bytes = Base64.decodeBase64(base64cert);
                    try {
                        CertificateFactory cf = CertificateFactory.getInstance(
                                "X.509");
                        this.cert = cf.generateCertificate(
                                new ByteArrayInputStream(bytes));
                    }
                    catch(CertificateException e) {
                        // should never occur
                        logger.error(e);
                    }
                }
            }
        }
    }

    public Certificate getCertificate() {
        return this.cert;
    }

    public byte[] getValue() {
        return this.value;
    }

    public String getReference() {
        // In theory there could be several references with digestvalues, ...
        return this.reference;
    }

    public byte[] getDigestValue() {
        return this.digestvalue;
    }
}
// vim: set si et fileencoding=utf-8 ts=4 sw=4 tw=80:

http://dive4elements.wald.intevation.org