All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jruby.ext.openssl.x509store.X509Utils Maven / Gradle / Ivy

/***** BEGIN LICENSE BLOCK *****
 * Version: CPL 1.0/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Common Public
 * License Version 1.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.eclipse.org/legal/cpl-v10.html
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * Copyright (C) 2006 Ola Bini 
 * 
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the CPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the CPL, the GPL or the LGPL.
 ***** END LICENSE BLOCK *****/
package org.jruby.ext.openssl.x509store;


import java.util.Arrays;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEREncodable;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;

/**
 * Contains most of the functionality that beings with X509 in
 * crypty/x509/x509_def.c, crypty/x509/x509_txt.c and others.
 *
 * @author Ola Bini
 */
@SuppressWarnings("deprecation")
public abstract class X509Utils {
    private X509Utils() {}

    /**
     * c: X509_get_default_private_dir
     */
    public static String getDefaultPrivateDir() {
        return X509_PRIVATE_DIR;
    }

    /**
     * c: X509_get_default_cert_area
     */
    public static String getDefaultCertificateArea() {
        return X509_CERT_AREA;
    }

    /**
     * c: X509_get_default_cert_dir
     */
    public static String getDefaultCertificateDirectory() {
        return X509_CERT_DIR;
    }

    /**
     * c: X509_get_default_cert_file
     */
    public static String getDefaultCertificateFile() {
        return X509_CERT_FILE;
    }

    /**
     * c: X509_get_default_cert_dir_env
     */
    public static String getDefaultCertificateDirectoryEnvironment() {
        return X509_CERT_DIR_EVP;
    }

    /**
     * c: X509_get_default_cert_file_env
     */
    public static String getDefaultCertificateFileEnvironment() {
        return X509_CERT_FILE_EVP;
    }

    /**
     * c: X509_verify_cert_error_string
     */
    public static String verifyCertificateErrorString(int n) {
	switch(n){
        case V_OK:
            return("ok");
	case V_ERR_UNABLE_TO_GET_ISSUER_CERT:
            return("unable to get issuer certificate");
	case V_ERR_UNABLE_TO_GET_CRL:
            return("unable to get certificate CRL");
	case V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
            return("unable to decrypt certificate's signature");
	case V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
            return("unable to decrypt CRL's signature");
	case V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
            return("unable to decode issuer public key");
	case V_ERR_CERT_SIGNATURE_FAILURE:
            return("certificate signature failure");
	case V_ERR_CRL_SIGNATURE_FAILURE:
            return("CRL signature failure");
	case V_ERR_CERT_NOT_YET_VALID:
            return("certificate is not yet valid");
	case V_ERR_CRL_NOT_YET_VALID:
            return("CRL is not yet valid");
	case V_ERR_CERT_HAS_EXPIRED:
            return("certificate has expired");
	case V_ERR_CRL_HAS_EXPIRED:
            return("CRL has expired");
	case V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
            return("format error in certificate's notBefore field");
	case V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
            return("format error in certificate's notAfter field");
	case V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
            return("format error in CRL's lastUpdate field");
	case V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
            return("format error in CRL's nextUpdate field");
	case V_ERR_OUT_OF_MEM:
            return("out of memory");
	case V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
            return("self signed certificate");
	case V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
            return("self signed certificate in certificate chain");
	case V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
            return("unable to get local issuer certificate");
	case V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
            return("unable to verify the first certificate");
	case V_ERR_CERT_CHAIN_TOO_LONG:
            return("certificate chain too long");
	case V_ERR_CERT_REVOKED:
            return("certificate revoked");
	case V_ERR_INVALID_CA:
            return ("invalid CA certificate");
	case V_ERR_INVALID_NON_CA:
            return ("invalid non-CA certificate (has CA markings)");
	case V_ERR_PATH_LENGTH_EXCEEDED:
            return ("path length constraint exceeded");
	case V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
            return("proxy path length constraint exceeded");
	case V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
            return("proxy cerificates not allowed, please set the appropriate flag");
	case V_ERR_INVALID_PURPOSE:
            return ("unsupported certificate purpose");
	case V_ERR_CERT_UNTRUSTED:
            return ("certificate not trusted");
	case V_ERR_CERT_REJECTED:
            return ("certificate rejected");
	case V_ERR_APPLICATION_VERIFICATION:
            return("application verification failure");
	case V_ERR_SUBJECT_ISSUER_MISMATCH:
            return("subject issuer mismatch");
	case V_ERR_AKID_SKID_MISMATCH:
            return("authority and subject key identifier mismatch");
	case V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
            return("authority and issuer serial number mismatch");
	case V_ERR_KEYUSAGE_NO_CERTSIGN:
            return("key usage does not include certificate signing");
	case V_ERR_UNABLE_TO_GET_CRL_ISSUER:
            return("unable to get CRL issuer certificate");
	case V_ERR_UNHANDLED_CRITICAL_EXTENSION:
            return("unhandled critical extension");
	case V_ERR_KEYUSAGE_NO_CRL_SIGN:
            return("key usage does not include CRL signing");
	case V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
            return("key usage does not include digital signature");
	case V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
            return("unhandled critical CRL extension");
	case V_ERR_INVALID_EXTENSION:
            return("invalid or inconsistent certificate extension");
	case V_ERR_INVALID_POLICY_EXTENSION:
            return("invalid or inconsistent certificate policy extension");
	case V_ERR_NO_EXPLICIT_POLICY:
            return("no explicit policy");
	default:
            return "error number " + n;
        }
    }

    private static Object get(Object str) throws Exception {
        return get(((DEROctetString)str).getOctets());
    }
    
    private static Object get(byte[] str) throws Exception {
        return new ASN1InputStream(str).readObject();
    }

    /**
     * c: X509_check_issued
     */
    public static int checkIfIssuedBy(X509AuxCertificate issuer, X509AuxCertificate subject) throws Exception { 
        if(!issuer.getSubjectX500Principal().equals(subject.getIssuerX500Principal())) {
            return V_ERR_SUBJECT_ISSUER_MISMATCH;
        }

        if(subject.getExtensionValue("2.5.29.35") != null) { //authorityKeyID
            // I hate ASN1 and DER
            Object key = get(subject.getExtensionValue("2.5.29.35"));
            if(!(key instanceof ASN1Sequence)) {
                key = get(key);
            }
            
            ASN1Sequence seq = (ASN1Sequence)key;
            AuthorityKeyIdentifier sakid = null;
            if(seq.size() == 1 && (seq.getObjectAt(0) instanceof ASN1OctetString)) {
                sakid = new AuthorityKeyIdentifier(new DERSequence(new DERTaggedObject(0, seq.getObjectAt(0))));
            } else {
                sakid = new AuthorityKeyIdentifier(seq);
            }

            if(sakid.getKeyIdentifier() != null) {
                if(issuer.getExtensionValue("2.5.29.14") != null) {
                    DEROctetString der = (DEROctetString)get(issuer.getExtensionValue("2.5.29.14"));
                    if(der.getOctets().length > 20) {
                        der = (DEROctetString)get(der.getOctets());
                    }
                    SubjectKeyIdentifier iskid = new SubjectKeyIdentifier(der);
                    if(iskid.getKeyIdentifier() != null) {
                        if(!Arrays.equals(sakid.getKeyIdentifier(),iskid.getKeyIdentifier())) {
                            return V_ERR_AKID_SKID_MISMATCH;
                        }
                    }
                }
            }
            if(sakid.getAuthorityCertSerialNumber() != null && !sakid.getAuthorityCertSerialNumber().equals(issuer.getSerialNumber())) {
                return V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
            }
            if(sakid.getAuthorityCertIssuer() != null) {
                GeneralName[] gens = sakid.getAuthorityCertIssuer().getNames();
                org.bouncycastle.asn1.x509.X509Name nm = null;
                for(int i=0;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy