Search in sources :

Example 11 with ExtendedKeyUsage

use of com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage in project keystore-explorer by kaikramer.

the class DExtendedKeyUsage method prepopulateWithValue.

private void prepopulateWithValue(byte[] value) throws IOException {
    ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance(value);
    for (KeyPurposeId keyPurposeId : extendedKeyUsage.getUsages()) {
        ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) keyPurposeId.toASN1Primitive();
        ExtendedKeyUsageType type = ExtendedKeyUsageType.resolveOid(oid.getId());
        if (type == SERVER_AUTH) {
            jcbTlsWebServerAuthentication.setSelected(true);
        } else if (type == CLIENT_AUTH) {
            jcbTlsWebClientAuthentication.setSelected(true);
        } else if (type == CODE_SIGNING) {
            jcbCodeSigning.setSelected(true);
        } else if (type == DOCUMENT_SIGNING) {
            jcbDocumentSigning.setSelected(true);
        } else if (type == ADOBE_PDF_SIGNING) {
            jcbAdobePDFSigning.setSelected(true);
        } else if (type == EMAIL_PROTECTION) {
            jcbEmailProtection.setSelected(true);
        } else if (type == ENCRYPTED_FILE_SYSTEM) {
            jcbEncryptedFileSystem.setSelected(true);
        } else if (type == IPSEC_END_SYSTEM) {
            jcbIpSecurityEndSystem.setSelected(true);
        } else if (type == IPSEC_TUNNEL) {
            jcbIpSecurityTunnelTermination.setSelected(true);
        } else if (type == IPSEC_USER) {
            jcbIpSecurityUser.setSelected(true);
        } else if (type == SMARTCARD_LOGON) {
            jcbSmartcardLogon.setSelected(true);
        } else if (type == TIME_STAMPING) {
            jcbTimeStamping.setSelected(true);
        } else if (type == OCSP_SIGNING) {
            jcbOcspStamping.setSelected(true);
        } else if (type == ANY_EXTENDED_KEY_USAGE) {
            jcbAnyExtendedKeyUsage.setSelected(true);
        }
    }
}
Also used : KeyPurposeId(org.bouncycastle.asn1.x509.KeyPurposeId) ExtendedKeyUsageType(org.kse.crypto.x509.ExtendedKeyUsageType) ExtendedKeyUsage(org.bouncycastle.asn1.x509.ExtendedKeyUsage) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 12 with ExtendedKeyUsage

use of com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage in project candlepin by candlepin.

the class BouncyCastlePKIUtility method createX509Certificate.

@Override
public X509Certificate createX509Certificate(String dn, Set<X509ExtensionWrapper> extensions, Set<X509ByteExtensionWrapper> byteExtensions, Date startDate, Date endDate, KeyPair clientKeyPair, BigInteger serialNumber, String alternateName) throws GeneralSecurityException, IOException {
    X509Certificate caCert = reader.getCACert();
    byte[] publicKeyEncoded = clientKeyPair.getPublic().getEncoded();
    X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(X500Name.getInstance(caCert.getSubjectX500Principal().getEncoded()), serialNumber, startDate, endDate, new X500Name(dn), SubjectPublicKeyInfo.getInstance(publicKeyEncoded));
    // set key usage - required for proper x509 function
    KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment);
    // add SSL extensions - required for proper x509 function
    NetscapeCertType certType = new NetscapeCertType(NetscapeCertType.sslClient | NetscapeCertType.smime);
    certGen.addExtension(MiscObjectIdentifiers.netscapeCertType, false, certType);
    certGen.addExtension(Extension.keyUsage, false, keyUsage);
    JcaX509ExtensionUtils extensionUtil = new JcaX509ExtensionUtils();
    AuthorityKeyIdentifier aki = extensionUtil.createAuthorityKeyIdentifier(caCert);
    certGen.addExtension(Extension.authorityKeyIdentifier, false, aki.getEncoded());
    certGen.addExtension(Extension.subjectKeyIdentifier, false, subjectKeyWriter.getSubjectKeyIdentifier(clientKeyPair, extensions));
    certGen.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));
    // Add an additional alternative name if provided.
    if (alternateName != null) {
        /*
             Why add the certificate subject again as an alternative name?  RFC 6125 Section 6.4.4
             stipulates that if SANs are provided, a validator MUST use them instead of the certificate
             subject.  If no SANs are present, the RFC allows the validator to use the subject field.  So,
             if we do have an SAN to add, we need to add the subject field again as an SAN.

             See http://stackoverflow.com/questions/5935369 and
             https://tools.ietf.org/html/rfc6125#section-6.4.4 and

             NB: These extensions should *not* be marked critical since the subject field is not empty.
            */
        GeneralName subject = new GeneralName(GeneralName.directoryName, dn);
        GeneralName name = new GeneralName(GeneralName.directoryName, "CN=" + alternateName);
        ASN1Encodable[] altNameArray = { subject, name };
        GeneralNames altNames = GeneralNames.getInstance(new DERSequence(altNameArray));
        certGen.addExtension(Extension.subjectAlternativeName, false, altNames);
    }
    if (extensions != null) {
        for (X509ExtensionWrapper wrapper : extensions) {
            // Bouncycastle hates null values. So, set them to blank
            // if they are null
            String value = wrapper.getValue() == null ? "" : wrapper.getValue();
            certGen.addExtension(wrapper.toASN1Primitive(), wrapper.isCritical(), new DERUTF8String(value));
        }
    }
    if (byteExtensions != null) {
        for (X509ByteExtensionWrapper wrapper : byteExtensions) {
            // Bouncycastle hates null values. So, set them to blank
            // if they are null
            byte[] value = wrapper.getValue() == null ? new byte[0] : wrapper.getValue();
            certGen.addExtension(wrapper.toASN1Primitive(), wrapper.isCritical(), new DEROctetString(value));
        }
    }
    JcaContentSignerBuilder builder = new JcaContentSignerBuilder(SIGNATURE_ALGO).setProvider(BC_PROVIDER);
    ContentSigner signer;
    try {
        signer = builder.build(reader.getCaKey());
    } catch (OperatorCreationException e) {
        throw new IOException(e);
    }
    // Generate the certificate
    return new JcaX509CertificateConverter().getCertificate(certGen.build(signer));
}
Also used : JcaX509ExtensionUtils(org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) ContentSigner(org.bouncycastle.operator.ContentSigner) KeyUsage(org.bouncycastle.asn1.x509.KeyUsage) ExtendedKeyUsage(org.bouncycastle.asn1.x509.ExtendedKeyUsage) AuthorityKeyIdentifier(org.bouncycastle.asn1.x509.AuthorityKeyIdentifier) X500Name(org.bouncycastle.asn1.x500.X500Name) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERSequence(org.bouncycastle.asn1.DERSequence) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) X509v3CertificateBuilder(org.bouncycastle.cert.X509v3CertificateBuilder) NetscapeCertType(org.bouncycastle.asn1.misc.NetscapeCertType) JcaX509CertificateConverter(org.bouncycastle.cert.jcajce.JcaX509CertificateConverter) X509ByteExtensionWrapper(org.candlepin.pki.X509ByteExtensionWrapper) X509ExtensionWrapper(org.candlepin.pki.X509ExtensionWrapper) GeneralName(org.bouncycastle.asn1.x509.GeneralName) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) ExtendedKeyUsage(org.bouncycastle.asn1.x509.ExtendedKeyUsage)

Example 13 with ExtendedKeyUsage

use of com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage in project jruby-openssl by jruby.

the class X509Extension method value.

@JRubyMethod
public RubyString value(final ThreadContext context) {
    if (this.value instanceof RubyString) {
        // return the same as set
        return (RubyString) this.value;
    }
    final Ruby runtime = context.runtime;
    final String oid = getRealObjectID().getId();
    try {
        if (oid.equals("2.5.29.19")) {
            // basicConstraints
            ASN1Sequence seq2 = (ASN1Sequence) ASN1.readObject(getRealValueEncoded());
            final ByteList val = new ByteList(32);
            if (seq2.size() > 0) {
                val.append(CA_);
                ASN1Encodable obj0 = seq2.getObjectAt(0);
                final boolean bool;
                if (obj0 instanceof ASN1Boolean) {
                    bool = ((ASN1Boolean) obj0).isTrue();
                } else {
                    // NOTE: keep it due BC <= 1.50
                    bool = ((DERBoolean) obj0).isTrue();
                }
                val.append(bool ? TRUE : FALSE);
            }
            if (seq2.size() > 1) {
                val.append(", pathlen:".getBytes());
                val.append(seq2.getObjectAt(1).toString().getBytes());
            }
            return runtime.newString(val);
        }
        if (oid.equals("2.5.29.15")) {
            // keyUsage
            final byte[] enc = getRealValueEncoded();
            byte b3 = 0;
            byte b2 = enc[2];
            if (enc.length > 3)
                b3 = enc[3];
            final ByteList val = new ByteList(64);
            byte[] sep = _;
            if ((b2 & (byte) 128) != 0) {
                val.append(sep);
                val.append(Decipher_Only);
                sep = SEP;
            }
            if ((b3 & (byte) 128) != 0) {
                val.append(sep);
                val.append(Digital_Signature);
                sep = SEP;
            }
            if ((b3 & (byte) 64) != 0) {
                val.append(sep);
                val.append(Non_Repudiation);
                sep = SEP;
            }
            if ((b3 & (byte) 32) != 0) {
                val.append(sep);
                val.append(Key_Encipherment);
                sep = SEP;
            }
            if ((b3 & (byte) 16) != 0) {
                val.append(sep);
                val.append(Data_Encipherment);
                sep = SEP;
            }
            if ((b3 & (byte) 8) != 0) {
                val.append(sep);
                val.append(Key_Agreement);
                sep = SEP;
            }
            if ((b3 & (byte) 4) != 0) {
                val.append(sep);
                val.append(Certificate_Sign);
                sep = SEP;
            }
            if ((b3 & (byte) 2) != 0) {
                val.append(sep);
                val.append(CRL_Sign);
                sep = SEP;
            }
            if ((b3 & (byte) 1) != 0) {
                // sep = SEP;
                val.append(sep);
                // sep = SEP;
                val.append(Encipher_Only);
            }
            return runtime.newString(val);
        }
        if (oid.equals("2.16.840.1.113730.1.1")) {
            // nsCertType
            final byte b0 = getRealValueEncoded()[0];
            final ByteList val = new ByteList(64);
            byte[] sep = _;
            if ((b0 & (byte) 128) != 0) {
                val.append(sep);
                val.append(SSL_Client);
                sep = SEP;
            }
            if ((b0 & (byte) 64) != 0) {
                val.append(sep);
                val.append(SSL_Server);
                sep = SEP;
            }
            if ((b0 & (byte) 32) != 0) {
                val.append(sep);
                val.append(SMIME);
                sep = SEP;
            }
            if ((b0 & (byte) 16) != 0) {
                val.append(sep);
                val.append(Object_Signing);
                sep = SEP;
            }
            if ((b0 & (byte) 8) != 0) {
                val.append(sep);
                val.append(Unused);
                sep = SEP;
            }
            if ((b0 & (byte) 4) != 0) {
                val.append(sep);
                val.append(SSL_CA);
                sep = SEP;
            }
            if ((b0 & (byte) 2) != 0) {
                val.append(sep);
                val.append(SMIME_CA);
                sep = SEP;
            }
            if ((b0 & (byte) 1) != 0) {
                val.append(sep);
                val.append(Object_Signing_CA);
            }
            return runtime.newString(val);
        }
        if (oid.equals("2.5.29.14")) {
            // subjectKeyIdentifier
            ASN1Encodable value = getRealValue();
            if (value instanceof ASN1OctetString) {
                byte[] octets = ((ASN1OctetString) value).getOctets();
                if (octets.length > 0 && octets[0] == BERTags.OCTET_STRING) {
                    // read nested octets
                    value = ASN1.readObject(octets);
                }
            }
            return runtime.newString(hexBytes(keyidBytes(value.toASN1Primitive()), 0));
        }
        if (oid.equals("2.5.29.35")) {
            // authorityKeyIdentifier
            ASN1Encodable value = getRealValue();
            if (value instanceof ASN1OctetString) {
                value = ASN1.readObject(((ASN1OctetString) value).getOctets());
            }
            final ByteList val = new ByteList(72);
            val.append(keyid_);
            if (value instanceof ASN1Sequence) {
                final ASN1Sequence seq = (ASN1Sequence) value;
                final int size = seq.size();
                if (size == 0)
                    return RubyString.newEmptyString(runtime);
                ASN1Primitive keyid = seq.getObjectAt(0).toASN1Primitive();
                hexBytes(keyidBytes(keyid), val).append('\n');
                for (int i = 1; i < size; i++) {
                    final ASN1Encodable issuer = seq.getObjectAt(i);
                    // NOTE: blindly got OpenSSL tests passing (likely in-complete) :
                    if (issuer instanceof ASN1TaggedObject) {
                        ASN1Primitive obj = ((ASN1TaggedObject) issuer).getObject();
                        switch(((ASN1TaggedObject) issuer).getTagNo()) {
                            case 1:
                                if (obj instanceof ASN1TaggedObject) {
                                    formatGeneralName(GeneralName.getInstance(obj), val, true);
                                }
                                break;
                            case // serial
                            2:
                                val.append(new byte[] { 's', 'e', 'r', 'i', 'a', 'l', ':' });
                                if (obj instanceof ASN1Integer) {
                                    hexBytes(((ASN1Integer) obj).getValue().toByteArray(), val);
                                } else {
                                    hexBytes(((ASN1OctetString) obj).getOctets(), val);
                                }
                                break;
                        }
                    }
                    val.append('\n');
                }
                return runtime.newString(val);
            }
            hexBytes(keyidBytes(value.toASN1Primitive()), val).append('\n');
            return runtime.newString(val);
        }
        if (oid.equals("2.5.29.21")) {
            // CRLReason
            final IRubyObject value = getValue(runtime);
            switch(RubyNumeric.fix2int(value)) {
                case 0:
                    return runtime.newString(new ByteList(Unspecified));
                case 1:
                    return RubyString.newString(runtime, "Key Compromise");
                case 2:
                    return RubyString.newString(runtime, "CA Compromise");
                case 3:
                    return RubyString.newString(runtime, "Affiliation Changed");
                case 4:
                    return RubyString.newString(runtime, "Superseded");
                case 5:
                    return RubyString.newString(runtime, "Cessation Of Operation");
                case 6:
                    return RubyString.newString(runtime, "Certificate Hold");
                case 8:
                    return RubyString.newString(runtime, "Remove From CRL");
                case 9:
                    return RubyString.newString(runtime, "Privilege Withdrawn");
                default:
                    return runtime.newString(new ByteList(Unspecified));
            }
        }
        if (oid.equals("2.5.29.17") || oid.equals("2.5.29.18")) {
            // subjectAltName || issuerAltName
            try {
                ASN1Encodable value = getRealValue();
                final ByteList val = new ByteList(64);
                if (value instanceof ASN1TaggedObject) {
                    formatGeneralName(GeneralName.getInstance(value), val, false);
                    return runtime.newString(val);
                }
                if (value instanceof GeneralName) {
                    formatGeneralName((GeneralName) value, val, false);
                    return runtime.newString(val);
                }
                if (value instanceof ASN1OctetString) {
                    // decoded octets will end up as an ASN1Sequence instance :
                    value = ASN1.readObject(((ASN1OctetString) value).getOctets());
                }
                if (value instanceof ASN1TaggedObject) {
                    // DERTaggedObject (issuerAltName wrapping)
                    formatGeneralName(GeneralName.getInstance(value), val, false);
                    return runtime.newString(val);
                }
                final GeneralName[] names = GeneralNames.getInstance(value).getNames();
                for (int i = 0; i < names.length; i++) {
                    boolean other = formatGeneralName(names[i], val, false);
                    if (i < names.length - 1) {
                        if (other)
                            val.append(';');
                        else
                            val.append(',').append(' ');
                    }
                }
                return runtime.newString(val);
            } catch (IllegalArgumentException e) {
                debugStackTrace(runtime, e);
                return rawValueAsString(context);
            }
        }
        if (oid.equals("2.5.29.37")) {
            // extendedKeyUsage
            final ByteList val = new ByteList(64);
            if (this.value instanceof ASN1Sequence) {
                // opt "short" path
                final ASN1Sequence seq = (ASN1Sequence) this.value;
                final int size = seq.size();
                for (int i = 0; i < size; i++) {
                    ASN1Encodable o = seq.getObjectAt(i);
                    String name = o.toString();
                    Integer nid = ASN1.oid2nid(runtime, new ASN1ObjectIdentifier(name));
                    if (nid != null)
                        name = ASN1.nid2ln(runtime, nid);
                    if (name == null)
                        name = o.toString();
                    val.append(ByteList.plain(name));
                    if (i < size - 1)
                        val.append(',').append(' ');
                }
                return runtime.newString(val);
            }
            final IRubyObject value = getValue(runtime);
            if (value instanceof RubyArray) {
                final RubyArray arr = (RubyArray) value;
                final int size = arr.size();
                for (int i = 0; i < size; i++) {
                    IRubyObject entry = arr.eltInternal(i);
                    if ("ObjectId".equals(entry.getMetaClass().getBaseName())) {
                        entry = entry.callMethod(context, "ln");
                    } else if (entry.respondsTo("value")) {
                        entry = entry.callMethod(context, "value");
                    }
                    val.append(entry.asString().getByteList());
                    if (i < size - 1)
                        val.append(',').append(' ');
                }
            }
            return runtime.newString(val);
        }
        return rawValueAsString(context);
    } catch (IOException e) {
        debugStackTrace(runtime, e);
        throw newExtensionError(runtime, e);
    }
}
Also used : ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) ByteList(org.jruby.util.ByteList) RubyArray(org.jruby.RubyArray) RubyString(org.jruby.RubyString) ASN1TaggedObject(org.bouncycastle.asn1.ASN1TaggedObject) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) RubyString(org.jruby.RubyString) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) ASN1String(org.bouncycastle.asn1.ASN1String) DERUniversalString(org.bouncycastle.asn1.DERUniversalString) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) IOException(java.io.IOException) IRubyObject(org.jruby.runtime.builtin.IRubyObject) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) ASN1Boolean(org.bouncycastle.asn1.ASN1Boolean) GeneralName(org.bouncycastle.asn1.x509.GeneralName) Ruby(org.jruby.Ruby) ASN1Primitive(org.bouncycastle.asn1.ASN1Primitive) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) JRubyMethod(org.jruby.anno.JRubyMethod)

Example 14 with ExtendedKeyUsage

use of com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage in project certmgr by hdecarne.

the class ExtendedKeyUsageController method init.

/**
 * Initialize the dialog with existing extension data.
 *
 * @param data The extension data to use.
 * @param expertMode Whether to run in expert mode ({@code true}) or not ({@code false}).
 * @return This controller.
 */
public ExtendedKeyUsageController init(ExtendedKeyUsageExtensionData data, boolean expertMode) {
    init(expertMode);
    this.ctlCritical.setSelected(data.getCritical());
    if (data.hasUsage(ExtendedKeyUsage.ANY)) {
        this.ctlAnyUsage.setSelected(true);
    } else {
        for (ExtendedKeyUsage usage : data) {
            this.ctlUsages.getSelectionModel().select(usage);
        }
    }
    return this;
}
Also used : ExtendedKeyUsage(de.carne.certmgr.certs.x509.ExtendedKeyUsage)

Example 15 with ExtendedKeyUsage

use of com.android.org.bouncycastle.asn1.x509.ExtendedKeyUsage in project xipki by xipki.

the class XmlX509Certprofile method getExtensions.

@Override
public ExtensionValues getExtensions(Map<ASN1ObjectIdentifier, ExtensionControl> extensionOccurences, X500Name requestedSubject, X500Name grantedSubject, Extensions requestedExtensions, Date notBefore, Date notAfter, PublicCaInfo caInfo) throws CertprofileException, BadCertTemplateException {
    ExtensionValues values = new ExtensionValues();
    if (CollectionUtil.isEmpty(extensionOccurences)) {
        return values;
    }
    ParamUtil.requireNonNull("requestedSubject", requestedSubject);
    ParamUtil.requireNonNull("notBefore", notBefore);
    ParamUtil.requireNonNull("notAfter", notAfter);
    Set<ASN1ObjectIdentifier> occurences = new HashSet<>(extensionOccurences.keySet());
    // AuthorityKeyIdentifier
    // processed by the CA
    // SubjectKeyIdentifier
    // processed by the CA
    // KeyUsage
    // processed by the CA
    // CertificatePolicies
    ASN1ObjectIdentifier type = Extension.certificatePolicies;
    if (certificatePolicies != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, certificatePolicies);
        }
    }
    // Policy Mappings
    type = Extension.policyMappings;
    if (policyMappings != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, policyMappings);
        }
    }
    // SubjectAltName
    type = Extension.subjectAlternativeName;
    if (occurences.contains(type)) {
        GeneralNames genNames = createRequestedSubjectAltNames(requestedSubject, grantedSubject, requestedExtensions);
        if (genNames != null) {
            ExtensionValue value = new ExtensionValue(extensionControls.get(type).isCritical(), genNames);
            values.addExtension(type, value);
            occurences.remove(type);
        }
    }
    // IssuerAltName
    // processed by the CA
    // Subject Directory Attributes
    type = Extension.subjectDirectoryAttributes;
    if (occurences.contains(type) && subjectDirAttrsControl != null) {
        Extension extension = (requestedExtensions == null) ? null : requestedExtensions.getExtension(type);
        if (extension == null) {
            throw new BadCertTemplateException("no SubjectDirecotryAttributes extension is contained in the request");
        }
        ASN1GeneralizedTime dateOfBirth = null;
        String placeOfBirth = null;
        String gender = null;
        List<String> countryOfCitizenshipList = new LinkedList<>();
        List<String> countryOfResidenceList = new LinkedList<>();
        Map<ASN1ObjectIdentifier, List<ASN1Encodable>> otherAttrs = new HashMap<>();
        Vector<?> reqSubDirAttrs = SubjectDirectoryAttributes.getInstance(extension.getParsedValue()).getAttributes();
        final int n = reqSubDirAttrs.size();
        for (int i = 0; i < n; i++) {
            Attribute attr = (Attribute) reqSubDirAttrs.get(i);
            ASN1ObjectIdentifier attrType = attr.getAttrType();
            ASN1Encodable attrVal = attr.getAttributeValues()[0];
            if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) {
                dateOfBirth = ASN1GeneralizedTime.getInstance(attrVal);
            } else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) {
                placeOfBirth = DirectoryString.getInstance(attrVal).getString();
            } else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) {
                gender = DERPrintableString.getInstance(attrVal).getString();
            } else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) {
                String country = DERPrintableString.getInstance(attrVal).getString();
                countryOfCitizenshipList.add(country);
            } else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) {
                String country = DERPrintableString.getInstance(attrVal).getString();
                countryOfResidenceList.add(country);
            } else {
                List<ASN1Encodable> otherAttrVals = otherAttrs.get(attrType);
                if (otherAttrVals == null) {
                    otherAttrVals = new LinkedList<>();
                    otherAttrs.put(attrType, otherAttrVals);
                }
                otherAttrVals.add(attrVal);
            }
        }
        Vector<Attribute> attrs = new Vector<>();
        for (ASN1ObjectIdentifier attrType : subjectDirAttrsControl.getTypes()) {
            if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) {
                if (dateOfBirth != null) {
                    String timeStirng = dateOfBirth.getTimeString();
                    if (!SubjectDnSpec.PATTERN_DATE_OF_BIRTH.matcher(timeStirng).matches()) {
                        throw new BadCertTemplateException("invalid dateOfBirth " + timeStirng);
                    }
                    attrs.add(new Attribute(attrType, new DERSet(dateOfBirth)));
                    continue;
                }
            } else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) {
                if (placeOfBirth != null) {
                    ASN1Encodable attrVal = new DERUTF8String(placeOfBirth);
                    attrs.add(new Attribute(attrType, new DERSet(attrVal)));
                    continue;
                }
            } else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) {
                if (gender != null && !gender.isEmpty()) {
                    char ch = gender.charAt(0);
                    if (!(gender.length() == 1 && (ch == 'f' || ch == 'F' || ch == 'm' || ch == 'M'))) {
                        throw new BadCertTemplateException("invalid gender " + gender);
                    }
                    ASN1Encodable attrVal = new DERPrintableString(gender);
                    attrs.add(new Attribute(attrType, new DERSet(attrVal)));
                    continue;
                }
            } else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) {
                if (!countryOfCitizenshipList.isEmpty()) {
                    for (String country : countryOfCitizenshipList) {
                        if (!SubjectDnSpec.isValidCountryAreaCode(country)) {
                            throw new BadCertTemplateException("invalid countryOfCitizenship code " + country);
                        }
                        ASN1Encodable attrVal = new DERPrintableString(country);
                        attrs.add(new Attribute(attrType, new DERSet(attrVal)));
                    }
                    continue;
                }
            } else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) {
                if (!countryOfResidenceList.isEmpty()) {
                    for (String country : countryOfResidenceList) {
                        if (!SubjectDnSpec.isValidCountryAreaCode(country)) {
                            throw new BadCertTemplateException("invalid countryOfResidence code " + country);
                        }
                        ASN1Encodable attrVal = new DERPrintableString(country);
                        attrs.add(new Attribute(attrType, new DERSet(attrVal)));
                    }
                    continue;
                }
            } else if (otherAttrs.containsKey(attrType)) {
                for (ASN1Encodable attrVal : otherAttrs.get(attrType)) {
                    attrs.add(new Attribute(attrType, new DERSet(attrVal)));
                }
                continue;
            }
            throw new BadCertTemplateException("could not process type " + attrType.getId() + " in extension SubjectDirectoryAttributes");
        }
        SubjectDirectoryAttributes subjDirAttrs = new SubjectDirectoryAttributes(attrs);
        ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), subjDirAttrs);
        values.addExtension(type, extValue);
        occurences.remove(type);
    }
    // Basic Constraints
    // processed by the CA
    // Name Constraints
    type = Extension.nameConstraints;
    if (nameConstraints != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, nameConstraints);
        }
    }
    // PolicyConstrains
    type = Extension.policyConstraints;
    if (policyConstraints != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, policyConstraints);
        }
    }
    // ExtendedKeyUsage
    // processed by CA
    // CRL Distribution Points
    // processed by the CA
    // Inhibit anyPolicy
    type = Extension.inhibitAnyPolicy;
    if (inhibitAnyPolicy != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, inhibitAnyPolicy);
        }
    }
    // Freshest CRL
    // processed by the CA
    // Authority Information Access
    // processed by the CA
    // Subject Information Access
    // processed by the CA
    // Admission
    type = ObjectIdentifiers.id_extension_admission;
    if (occurences.contains(type) && admission != null) {
        if (admission.isInputFromRequestRequired()) {
            Extension extension = (requestedExtensions == null) ? null : requestedExtensions.getExtension(type);
            if (extension == null) {
                throw new BadCertTemplateException("No Admission extension is contained in the request");
            }
            Admissions[] reqAdmissions = org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax.getInstance(extension.getParsedValue()).getContentsOfAdmissions();
            final int n = reqAdmissions.length;
            List<List<String>> reqRegNumsList = new ArrayList<>(n);
            for (int i = 0; i < n; i++) {
                Admissions reqAdmission = reqAdmissions[i];
                ProfessionInfo[] reqPis = reqAdmission.getProfessionInfos();
                List<String> reqNums = new ArrayList<>(reqPis.length);
                reqRegNumsList.add(reqNums);
                for (ProfessionInfo reqPi : reqPis) {
                    String reqNum = reqPi.getRegistrationNumber();
                    reqNums.add(reqNum);
                }
            }
            values.addExtension(type, admission.getExtensionValue(reqRegNumsList));
            occurences.remove(type);
        } else {
            values.addExtension(type, admission.getExtensionValue(null));
            occurences.remove(type);
        }
    }
    // OCSP Nocheck
    // processed by the CA
    // restriction
    type = ObjectIdentifiers.id_extension_restriction;
    if (restriction != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, restriction);
        }
    }
    // AdditionalInformation
    type = ObjectIdentifiers.id_extension_additionalInformation;
    if (additionalInformation != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, additionalInformation);
        }
    }
    // ValidityModel
    type = ObjectIdentifiers.id_extension_validityModel;
    if (validityModel != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, validityModel);
        }
    }
    // PrivateKeyUsagePeriod
    type = Extension.privateKeyUsagePeriod;
    if (occurences.contains(type)) {
        Date tmpNotAfter;
        if (privateKeyUsagePeriod == null) {
            tmpNotAfter = notAfter;
        } else {
            tmpNotAfter = privateKeyUsagePeriod.add(notBefore);
            if (tmpNotAfter.after(notAfter)) {
                tmpNotAfter = notAfter;
            }
        }
        ASN1EncodableVector vec = new ASN1EncodableVector();
        vec.add(new DERTaggedObject(false, 0, new DERGeneralizedTime(notBefore)));
        vec.add(new DERTaggedObject(false, 1, new DERGeneralizedTime(tmpNotAfter)));
        ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), new DERSequence(vec));
        values.addExtension(type, extValue);
        occurences.remove(type);
    }
    // QCStatements
    type = Extension.qCStatements;
    if (occurences.contains(type) && (qcStatments != null || qcStatementsOption != null)) {
        if (qcStatments != null) {
            values.addExtension(type, qcStatments);
            occurences.remove(type);
        } else if (requestedExtensions != null && qcStatementsOption != null) {
            // extract the euLimit data from request
            Extension extension = requestedExtensions.getExtension(type);
            if (extension == null) {
                throw new BadCertTemplateException("No QCStatement extension is contained in the request");
            }
            ASN1Sequence seq = ASN1Sequence.getInstance(extension.getParsedValue());
            Map<String, int[]> qcEuLimits = new HashMap<>();
            final int n = seq.size();
            for (int i = 0; i < n; i++) {
                QCStatement stmt = QCStatement.getInstance(seq.getObjectAt(i));
                if (!ObjectIdentifiers.id_etsi_qcs_QcLimitValue.equals(stmt.getStatementId())) {
                    continue;
                }
                MonetaryValue monetaryValue = MonetaryValue.getInstance(stmt.getStatementInfo());
                int amount = monetaryValue.getAmount().intValue();
                int exponent = monetaryValue.getExponent().intValue();
                Iso4217CurrencyCode currency = monetaryValue.getCurrency();
                String currencyS = currency.isAlphabetic() ? currency.getAlphabetic().toUpperCase() : Integer.toString(currency.getNumeric());
                qcEuLimits.put(currencyS, new int[] { amount, exponent });
            }
            ASN1EncodableVector vec = new ASN1EncodableVector();
            for (QcStatementOption m : qcStatementsOption) {
                if (m.getStatement() != null) {
                    vec.add(m.getStatement());
                    continue;
                }
                MonetaryValueOption monetaryOption = m.getMonetaryValueOption();
                String currencyS = monetaryOption.getCurrencyString();
                int[] limit = qcEuLimits.get(currencyS);
                if (limit == null) {
                    throw new BadCertTemplateException("no EuLimitValue is specified for currency '" + currencyS + "'");
                }
                int amount = limit[0];
                Range2Type range = monetaryOption.getAmountRange();
                if (amount < range.getMin() || amount > range.getMax()) {
                    throw new BadCertTemplateException("amount for currency '" + currencyS + "' is not within [" + range.getMin() + ", " + range.getMax() + "]");
                }
                int exponent = limit[1];
                range = monetaryOption.getExponentRange();
                if (exponent < range.getMin() || exponent > range.getMax()) {
                    throw new BadCertTemplateException("exponent for currency '" + currencyS + "' is not within [" + range.getMin() + ", " + range.getMax() + "]");
                }
                MonetaryValue monetaryVale = new MonetaryValue(monetaryOption.getCurrency(), amount, exponent);
                QCStatement qcStatment = new QCStatement(m.getStatementId(), monetaryVale);
                vec.add(qcStatment);
            }
            ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), new DERSequence(vec));
            values.addExtension(type, extValue);
            occurences.remove(type);
        } else {
            throw new RuntimeException("should not reach here");
        }
    }
    // BiometricData
    type = Extension.biometricInfo;
    if (occurences.contains(type) && biometricInfo != null) {
        Extension extension = (requestedExtensions == null) ? null : requestedExtensions.getExtension(type);
        if (extension == null) {
            throw new BadCertTemplateException("no biometricInfo extension is contained in the request");
        }
        ASN1Sequence seq = ASN1Sequence.getInstance(extension.getParsedValue());
        final int n = seq.size();
        if (n < 1) {
            throw new BadCertTemplateException("biometricInfo extension in request contains empty sequence");
        }
        ASN1EncodableVector vec = new ASN1EncodableVector();
        for (int i = 0; i < n; i++) {
            BiometricData bd = BiometricData.getInstance(seq.getObjectAt(i));
            TypeOfBiometricData bdType = bd.getTypeOfBiometricData();
            if (!biometricInfo.isTypePermitted(bdType)) {
                throw new BadCertTemplateException("biometricInfo[" + i + "].typeOfBiometricData is not permitted");
            }
            ASN1ObjectIdentifier hashAlgo = bd.getHashAlgorithm().getAlgorithm();
            if (!biometricInfo.isHashAlgorithmPermitted(hashAlgo)) {
                throw new BadCertTemplateException("biometricInfo[" + i + "].hashAlgorithm is not permitted");
            }
            int expHashValueSize;
            try {
                expHashValueSize = AlgorithmUtil.getHashOutputSizeInOctets(hashAlgo);
            } catch (NoSuchAlgorithmException ex) {
                throw new CertprofileException("should not happen, unknown hash algorithm " + hashAlgo);
            }
            byte[] hashValue = bd.getBiometricDataHash().getOctets();
            if (hashValue.length != expHashValueSize) {
                throw new BadCertTemplateException("biometricInfo[" + i + "].biometricDataHash has incorrect length");
            }
            DERIA5String sourceDataUri = bd.getSourceDataUri();
            switch(biometricInfo.getSourceDataUriOccurrence()) {
                case FORBIDDEN:
                    sourceDataUri = null;
                    break;
                case REQUIRED:
                    if (sourceDataUri == null) {
                        throw new BadCertTemplateException("biometricInfo[" + i + "].sourceDataUri is not specified in request but is required");
                    }
                    break;
                case OPTIONAL:
                    break;
                default:
                    throw new BadCertTemplateException("could not reach here, unknown tripleState");
            }
            AlgorithmIdentifier newHashAlg = new AlgorithmIdentifier(hashAlgo, DERNull.INSTANCE);
            BiometricData newBiometricData = new BiometricData(bdType, newHashAlg, new DEROctetString(hashValue), sourceDataUri);
            vec.add(newBiometricData);
        }
        ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), new DERSequence(vec));
        values.addExtension(type, extValue);
        occurences.remove(type);
    }
    // TlsFeature
    type = ObjectIdentifiers.id_pe_tlsfeature;
    if (tlsFeature != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, tlsFeature);
        }
    }
    // AuthorizationTemplate
    type = ObjectIdentifiers.id_xipki_ext_authorizationTemplate;
    if (authorizationTemplate != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, authorizationTemplate);
        }
    }
    // SMIME
    type = ObjectIdentifiers.id_smimeCapabilities;
    if (smimeCapabilities != null) {
        if (occurences.remove(type)) {
            values.addExtension(type, smimeCapabilities);
        }
    }
    // constant extensions
    if (constantExtensions != null) {
        for (ASN1ObjectIdentifier m : constantExtensions.keySet()) {
            if (!occurences.remove(m)) {
                continue;
            }
            ExtensionValue extensionValue = constantExtensions.get(m);
            if (extensionValue != null) {
                values.addExtension(m, extensionValue);
            }
        }
    }
    ExtensionValues extraExtensions = getExtraExtensions(extensionOccurences, requestedSubject, grantedSubject, requestedExtensions, notBefore, notAfter, caInfo);
    if (extraExtensions != null) {
        for (ASN1ObjectIdentifier m : extraExtensions.getExtensionTypes()) {
            values.addExtension(m, extraExtensions.getExtensionValue(m));
        }
    }
    return values;
}
Also used : BiometricData(org.bouncycastle.asn1.x509.qualified.BiometricData) TypeOfBiometricData(org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) DirectoryString(org.bouncycastle.asn1.x500.DirectoryString) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) DEROctetString(org.bouncycastle.asn1.DEROctetString) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) DERSequence(org.bouncycastle.asn1.DERSequence) ExtensionValue(org.xipki.ca.api.profile.ExtensionValue) DERGeneralizedTime(org.bouncycastle.asn1.DERGeneralizedTime) Range2Type(org.xipki.ca.certprofile.x509.jaxb.Range2Type) CertprofileException(org.xipki.ca.api.profile.CertprofileException) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) ASN1EncodableVector(org.bouncycastle.asn1.ASN1EncodableVector) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) ExtensionValues(org.xipki.ca.api.profile.ExtensionValues) Vector(java.util.Vector) ASN1EncodableVector(org.bouncycastle.asn1.ASN1EncodableVector) TypeOfBiometricData(org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData) HashSet(java.util.HashSet) LinkedList(java.util.LinkedList) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) BadCertTemplateException(org.xipki.ca.api.BadCertTemplateException) Map(java.util.Map) HashMap(java.util.HashMap) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) QCStatement(org.bouncycastle.asn1.x509.qualified.QCStatement) Attribute(org.bouncycastle.asn1.x509.Attribute) ASN1GeneralizedTime(org.bouncycastle.asn1.ASN1GeneralizedTime) DERSet(org.bouncycastle.asn1.DERSet) Iso4217CurrencyCode(org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode) DERIA5String(org.bouncycastle.asn1.DERIA5String) Admissions(org.bouncycastle.asn1.isismtt.x509.Admissions) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) ProfessionInfo(org.bouncycastle.asn1.isismtt.x509.ProfessionInfo) DERTaggedObject(org.bouncycastle.asn1.DERTaggedObject) SubjectDirectoryAttributes(org.bouncycastle.asn1.x509.SubjectDirectoryAttributes) MonetaryValue(org.bouncycastle.asn1.x509.qualified.MonetaryValue) Date(java.util.Date) Extension(org.bouncycastle.asn1.x509.Extension)

Aggregations

ExtendedKeyUsage (org.bouncycastle.asn1.x509.ExtendedKeyUsage)25 KeyPurposeId (org.bouncycastle.asn1.x509.KeyPurposeId)18 KeyUsage (org.bouncycastle.asn1.x509.KeyUsage)14 X500Name (org.bouncycastle.asn1.x500.X500Name)13 BasicConstraints (org.bouncycastle.asn1.x509.BasicConstraints)13 X509v3CertificateBuilder (org.bouncycastle.cert.X509v3CertificateBuilder)13 JcaContentSignerBuilder (org.bouncycastle.operator.jcajce.JcaContentSignerBuilder)13 Date (java.util.Date)12 JcaX509CertificateConverter (org.bouncycastle.cert.jcajce.JcaX509CertificateConverter)12 ContentSigner (org.bouncycastle.operator.ContentSigner)11 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)10 Extension (org.bouncycastle.asn1.x509.Extension)9 X509Certificate (java.security.cert.X509Certificate)8 HashSet (java.util.HashSet)8 DEROctetString (org.bouncycastle.asn1.DEROctetString)8 SubjectPublicKeyInfo (org.bouncycastle.asn1.x509.SubjectPublicKeyInfo)8 CertificateException (java.security.cert.CertificateException)7 DERIA5String (org.bouncycastle.asn1.DERIA5String)7 GeneralName (org.bouncycastle.asn1.x509.GeneralName)7 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)6