Search in sources :

Example 6 with SubjectKeyIdentifier

use of org.bouncycastle.asn1.x509.SubjectKeyIdentifier in project xipki by xipki.

the class ExtensionsChecker method checkExtensionSubjectKeyIdentifier.

// method checkExtensionBasicConstraints
private void checkExtensionSubjectKeyIdentifier(StringBuilder failureMsg, byte[] extensionValue, SubjectPublicKeyInfo subjectPublicKeyInfo) {
    // subjectKeyIdentifier
    SubjectKeyIdentifier asn1 = SubjectKeyIdentifier.getInstance(extensionValue);
    byte[] ski = asn1.getKeyIdentifier();
    byte[] pkData = subjectPublicKeyInfo.getPublicKeyData().getBytes();
    byte[] expectedSki = HashAlgo.SHA1.hash(pkData);
    if (!Arrays.equals(expectedSki, ski)) {
        addViolation(failureMsg, "SKI", hex(ski), hex(expectedSki));
    }
}
Also used : SubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectKeyIdentifier)

Example 7 with SubjectKeyIdentifier

use of org.bouncycastle.asn1.x509.SubjectKeyIdentifier in project xipki by xipki.

the class ExtensionsChecker method checkExtensions.

// constructor
public List<ValidationIssue> checkExtensions(Certificate cert, X509IssuerInfo issuerInfo, Extensions requestedExtensions, X500Name requestedSubject) {
    ParamUtil.requireNonNull("cert", cert);
    ParamUtil.requireNonNull("issuerInfo", issuerInfo);
    X509Certificate jceCert;
    try {
        jceCert = X509Util.toX509Cert(cert);
    } catch (CertificateException ex) {
        throw new IllegalArgumentException("invalid cert: " + ex.getMessage());
    }
    List<ValidationIssue> result = new LinkedList<>();
    // detect the list of extension types in certificate
    Set<ASN1ObjectIdentifier> presentExtenionTypes = getExensionTypes(cert, issuerInfo, requestedExtensions);
    Extensions extensions = cert.getTBSCertificate().getExtensions();
    ASN1ObjectIdentifier[] oids = extensions.getExtensionOIDs();
    if (oids == null) {
        ValidationIssue issue = new ValidationIssue("X509.EXT.GEN", "extension general");
        result.add(issue);
        issue.setFailureMessage("no extension is present");
        return result;
    }
    List<ASN1ObjectIdentifier> certExtTypes = Arrays.asList(oids);
    for (ASN1ObjectIdentifier extType : presentExtenionTypes) {
        if (!certExtTypes.contains(extType)) {
            ValidationIssue issue = createExtensionIssue(extType);
            result.add(issue);
            issue.setFailureMessage("extension is absent but is required");
        }
    }
    Map<ASN1ObjectIdentifier, ExtensionControl> extensionControls = certProfile.getExtensionControls();
    for (ASN1ObjectIdentifier oid : certExtTypes) {
        ValidationIssue issue = createExtensionIssue(oid);
        result.add(issue);
        if (!presentExtenionTypes.contains(oid)) {
            issue.setFailureMessage("extension is present but is not permitted");
            continue;
        }
        Extension ext = extensions.getExtension(oid);
        StringBuilder failureMsg = new StringBuilder();
        ExtensionControl extControl = extensionControls.get(oid);
        if (extControl.isCritical() != ext.isCritical()) {
            addViolation(failureMsg, "critical", ext.isCritical(), extControl.isCritical());
        }
        byte[] extensionValue = ext.getExtnValue().getOctets();
        try {
            if (Extension.authorityKeyIdentifier.equals(oid)) {
                // AuthorityKeyIdentifier
                checkExtensionIssuerKeyIdentifier(failureMsg, extensionValue, issuerInfo);
            } else if (Extension.subjectKeyIdentifier.equals(oid)) {
                // SubjectKeyIdentifier
                checkExtensionSubjectKeyIdentifier(failureMsg, extensionValue, cert.getSubjectPublicKeyInfo());
            } else if (Extension.keyUsage.equals(oid)) {
                // KeyUsage
                checkExtensionKeyUsage(failureMsg, extensionValue, jceCert.getKeyUsage(), requestedExtensions, extControl);
            } else if (Extension.certificatePolicies.equals(oid)) {
                // CertificatePolicies
                checkExtensionCertificatePolicies(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (Extension.policyMappings.equals(oid)) {
                // Policy Mappings
                checkExtensionPolicyMappings(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (Extension.subjectAlternativeName.equals(oid)) {
                // SubjectAltName
                checkExtensionSubjectAltName(failureMsg, extensionValue, requestedExtensions, extControl, requestedSubject);
            } else if (Extension.subjectDirectoryAttributes.equals(oid)) {
                // SubjectDirectoryAttributes
                checkExtensionSubjectDirAttrs(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (Extension.issuerAlternativeName.equals(oid)) {
                // IssuerAltName
                checkExtensionIssuerAltNames(failureMsg, extensionValue, issuerInfo);
            } else if (Extension.basicConstraints.equals(oid)) {
                // Basic Constraints
                checkExtensionBasicConstraints(failureMsg, extensionValue);
            } else if (Extension.nameConstraints.equals(oid)) {
                // Name Constraints
                checkExtensionNameConstraints(failureMsg, extensionValue, extensions, extControl);
            } else if (Extension.policyConstraints.equals(oid)) {
                // PolicyConstrains
                checkExtensionPolicyConstraints(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (Extension.extendedKeyUsage.equals(oid)) {
                // ExtendedKeyUsage
                checkExtensionExtendedKeyUsage(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (Extension.cRLDistributionPoints.equals(oid)) {
                // CRL Distribution Points
                checkExtensionCrlDistributionPoints(failureMsg, extensionValue, issuerInfo);
            } else if (Extension.inhibitAnyPolicy.equals(oid)) {
                // Inhibit anyPolicy
                checkExtensionInhibitAnyPolicy(failureMsg, extensionValue, extensions, extControl);
            } else if (Extension.freshestCRL.equals(oid)) {
                // Freshest CRL
                checkExtensionDeltaCrlDistributionPoints(failureMsg, extensionValue, issuerInfo);
            } else if (Extension.authorityInfoAccess.equals(oid)) {
                // Authority Information Access
                checkExtensionAuthorityInfoAccess(failureMsg, extensionValue, issuerInfo);
            } else if (Extension.subjectInfoAccess.equals(oid)) {
                // SubjectInfoAccess
                checkExtensionSubjectInfoAccess(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (ObjectIdentifiers.id_extension_admission.equals(oid)) {
                // Admission
                checkExtensionAdmission(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (ObjectIdentifiers.id_extension_pkix_ocsp_nocheck.equals(oid)) {
                // ocsp-nocheck
                checkExtensionOcspNocheck(failureMsg, extensionValue);
            } else if (ObjectIdentifiers.id_extension_restriction.equals(oid)) {
                // restriction
                checkExtensionRestriction(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (ObjectIdentifiers.id_extension_additionalInformation.equals(oid)) {
                // additionalInformation
                checkExtensionAdditionalInformation(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (ObjectIdentifiers.id_extension_validityModel.equals(oid)) {
                // validityModel
                checkExtensionValidityModel(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (Extension.privateKeyUsagePeriod.equals(oid)) {
                // privateKeyUsagePeriod
                checkExtensionPrivateKeyUsagePeriod(failureMsg, extensionValue, jceCert.getNotBefore(), jceCert.getNotAfter());
            } else if (Extension.qCStatements.equals(oid)) {
                // qCStatements
                checkExtensionQcStatements(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (Extension.biometricInfo.equals(oid)) {
                // biometricInfo
                checkExtensionBiometricInfo(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (ObjectIdentifiers.id_pe_tlsfeature.equals(oid)) {
                // tlsFeature
                checkExtensionTlsFeature(failureMsg, extensionValue, requestedExtensions, extControl);
            } else if (ObjectIdentifiers.id_xipki_ext_authorizationTemplate.equals(oid)) {
                // authorizationTemplate
                checkExtensionAuthorizationTemplate(failureMsg, extensionValue, requestedExtensions, extControl);
            } else {
                byte[] expected;
                if (ObjectIdentifiers.id_smimeCapabilities.equals(oid)) {
                    // SMIMECapabilities
                    expected = smimeCapabilities.getValue();
                } else {
                    expected = getExpectedExtValue(oid, requestedExtensions, extControl);
                }
                if (!Arrays.equals(expected, extensionValue)) {
                    addViolation(failureMsg, "extension valus", hex(extensionValue), (expected == null) ? "not present" : hex(expected));
                }
            }
            if (failureMsg.length() > 0) {
                issue.setFailureMessage(failureMsg.toString());
            }
        } catch (IllegalArgumentException | ClassCastException | ArrayIndexOutOfBoundsException ex) {
            LOG.debug("extension value does not have correct syntax", ex);
            issue.setFailureMessage("extension value does not have correct syntax");
        }
    }
    return result;
}
Also used : CertificateException(java.security.cert.CertificateException) Extensions(org.bouncycastle.asn1.x509.Extensions) ValidationIssue(org.xipki.common.qa.ValidationIssue) X509Certificate(java.security.cert.X509Certificate) LinkedList(java.util.LinkedList) Extension(org.bouncycastle.asn1.x509.Extension) ExtensionControl(org.xipki.ca.api.profile.ExtensionControl) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 8 with SubjectKeyIdentifier

use of org.bouncycastle.asn1.x509.SubjectKeyIdentifier in project xipki by xipki.

the class IdentifiedX509Certprofile method getExtensions.

/**
 * TODO.
 * @param requestedSubject
 *          Subject requested subject. Must not be {@code null}.
 * @param grantedSubject
 *          Granted subject. Must not be {@code null}.
 * @param requestedExtensions
 *          Extensions requested by the requestor. Could be {@code null}.
 * @param publicKeyInfo
 *          Subject public key. Must not be {@code null}.
 * @param publicCaInfo
 *          CA information. Must not be {@code null}.
 * @param crlSignerCert
 *          CRL signer certificate. Could be {@code null}.
 * @param notBefore
 *          NotBefore. Must not be {@code null}.
 * @param notAfter
 *          NotAfter. Must not be {@code null}.
 * @param caInfo
 *          CA information.
 * @return the extensions of the certificate to be issued.
 */
public ExtensionValues getExtensions(X500Name requestedSubject, X500Name grantedSubject, Extensions requestedExtensions, SubjectPublicKeyInfo publicKeyInfo, PublicCaInfo publicCaInfo, X509Certificate crlSignerCert, Date notBefore, Date notAfter) throws CertprofileException, BadCertTemplateException {
    ParamUtil.requireNonNull("publicKeyInfo", publicKeyInfo);
    ExtensionValues values = new ExtensionValues();
    Map<ASN1ObjectIdentifier, ExtensionControl> controls = new HashMap<>(certprofile.getExtensionControls());
    Set<ASN1ObjectIdentifier> neededExtTypes = new HashSet<>();
    Set<ASN1ObjectIdentifier> wantedExtTypes = new HashSet<>();
    if (requestedExtensions != null) {
        Extension reqExtension = requestedExtensions.getExtension(ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions);
        if (reqExtension != null) {
            ExtensionExistence ee = ExtensionExistence.getInstance(reqExtension.getParsedValue());
            neededExtTypes.addAll(ee.getNeedExtensions());
            wantedExtTypes.addAll(ee.getWantExtensions());
        }
        for (ASN1ObjectIdentifier oid : neededExtTypes) {
            if (wantedExtTypes.contains(oid)) {
                wantedExtTypes.remove(oid);
            }
            if (!controls.containsKey(oid)) {
                throw new BadCertTemplateException("could not add needed extension " + oid.getId());
            }
        }
    }
    // SubjectKeyIdentifier
    ASN1ObjectIdentifier extType = Extension.subjectKeyIdentifier;
    ExtensionControl extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        byte[] encodedSpki = publicKeyInfo.getPublicKeyData().getBytes();
        byte[] skiValue = HashAlgo.SHA1.hash(encodedSpki);
        SubjectKeyIdentifier value = new SubjectKeyIdentifier(skiValue);
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // Authority key identifier
    extType = Extension.authorityKeyIdentifier;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        byte[] ikiValue = publicCaInfo.getSubjectKeyIdentifer();
        AuthorityKeyIdentifier value = null;
        if (ikiValue != null) {
            if (certprofile.includesIssuerAndSerialInAki()) {
                GeneralNames x509CaSubject = new GeneralNames(new GeneralName(publicCaInfo.getX500Subject()));
                value = new AuthorityKeyIdentifier(ikiValue, x509CaSubject, publicCaInfo.getSerialNumber());
            } else {
                value = new AuthorityKeyIdentifier(ikiValue);
            }
        }
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // IssuerAltName
    extType = Extension.issuerAlternativeName;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        GeneralNames value = publicCaInfo.getSubjectAltName();
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // AuthorityInfoAccess
    extType = Extension.authorityInfoAccess;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        AuthorityInfoAccessControl aiaControl = certprofile.getAiaControl();
        List<String> caIssuers = null;
        if (aiaControl == null || aiaControl.isIncludesCaIssuers()) {
            caIssuers = publicCaInfo.getCaCertUris();
        }
        List<String> ocspUris = null;
        if (aiaControl == null || aiaControl.isIncludesOcsp()) {
            ocspUris = publicCaInfo.getOcspUris();
        }
        if (CollectionUtil.isNonEmpty(caIssuers) || CollectionUtil.isNonEmpty(ocspUris)) {
            AuthorityInformationAccess value = CaUtil.createAuthorityInformationAccess(caIssuers, ocspUris);
            addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
        }
    }
    if (controls.containsKey(Extension.cRLDistributionPoints) || controls.containsKey(Extension.freshestCRL)) {
        X500Name crlSignerSubject = (crlSignerCert == null) ? null : X500Name.getInstance(crlSignerCert.getSubjectX500Principal().getEncoded());
        X500Name x500CaPrincipal = publicCaInfo.getX500Subject();
        // CRLDistributionPoints
        extType = Extension.cRLDistributionPoints;
        extControl = controls.remove(extType);
        if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
            if (CollectionUtil.isNonEmpty(publicCaInfo.getCrlUris())) {
                CRLDistPoint value = CaUtil.createCrlDistributionPoints(publicCaInfo.getCrlUris(), x500CaPrincipal, crlSignerSubject);
                addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
            }
        }
        // FreshestCRL
        extType = Extension.freshestCRL;
        extControl = controls.remove(extType);
        if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
            if (CollectionUtil.isNonEmpty(publicCaInfo.getDeltaCrlUris())) {
                CRLDistPoint value = CaUtil.createCrlDistributionPoints(publicCaInfo.getDeltaCrlUris(), x500CaPrincipal, crlSignerSubject);
                addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
            }
        }
    }
    // BasicConstraints
    extType = Extension.basicConstraints;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        BasicConstraints value = CaUtil.createBasicConstraints(certprofile.getCertLevel(), certprofile.getPathLenBasicConstraint());
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // KeyUsage
    extType = Extension.keyUsage;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        Set<KeyUsage> usages = new HashSet<>();
        Set<KeyUsageControl> usageOccs = certprofile.getKeyUsage();
        for (KeyUsageControl k : usageOccs) {
            if (k.isRequired()) {
                usages.add(k.getKeyUsage());
            }
        }
        // the optional KeyUsage will only be set if requested explicitly
        if (requestedExtensions != null && extControl.isRequest()) {
            addRequestedKeyusage(usages, requestedExtensions, usageOccs);
        }
        org.bouncycastle.asn1.x509.KeyUsage value = X509Util.createKeyUsage(usages);
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // ExtendedKeyUsage
    extType = Extension.extendedKeyUsage;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        List<ASN1ObjectIdentifier> usages = new LinkedList<>();
        Set<ExtKeyUsageControl> usageOccs = certprofile.getExtendedKeyUsages();
        for (ExtKeyUsageControl k : usageOccs) {
            if (k.isRequired()) {
                usages.add(k.getExtKeyUsage());
            }
        }
        // the optional ExtKeyUsage will only be set if requested explicitly
        if (requestedExtensions != null && extControl.isRequest()) {
            addRequestedExtKeyusage(usages, requestedExtensions, usageOccs);
        }
        if (extControl.isCritical() && usages.contains(ObjectIdentifiers.id_anyExtendedKeyUsage)) {
            extControl = new ExtensionControl(false, extControl.isRequired(), extControl.isRequest());
        }
        ExtendedKeyUsage value = X509Util.createExtendedUsage(usages);
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // ocsp-nocheck
    extType = ObjectIdentifiers.id_extension_pkix_ocsp_nocheck;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        // the extension ocsp-nocheck will only be set if requested explicitly
        DERNull value = DERNull.INSTANCE;
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // SubjectInfoAccess
    extType = Extension.subjectInfoAccess;
    extControl = controls.remove(extType);
    if (extControl != null && addMe(extType, extControl, neededExtTypes, wantedExtTypes)) {
        ASN1Sequence value = null;
        if (requestedExtensions != null && extControl.isRequest()) {
            value = createSubjectInfoAccess(requestedExtensions, certprofile.getSubjectInfoAccessModes());
        }
        addExtension(values, extType, value, extControl, neededExtTypes, wantedExtTypes);
    }
    // remove extensions that are not required frrom the list
    List<ASN1ObjectIdentifier> listToRm = null;
    for (ASN1ObjectIdentifier extnType : controls.keySet()) {
        ExtensionControl ctrl = controls.get(extnType);
        if (ctrl.isRequired()) {
            continue;
        }
        if (neededExtTypes.contains(extnType) || wantedExtTypes.contains(extnType)) {
            continue;
        }
        if (listToRm == null) {
            listToRm = new LinkedList<>();
        }
        listToRm.add(extnType);
    }
    if (listToRm != null) {
        for (ASN1ObjectIdentifier extnType : listToRm) {
            controls.remove(extnType);
        }
    }
    ExtensionValues subvalues = certprofile.getExtensions(Collections.unmodifiableMap(controls), requestedSubject, grantedSubject, requestedExtensions, notBefore, notAfter, publicCaInfo);
    Set<ASN1ObjectIdentifier> extTypes = new HashSet<>(controls.keySet());
    for (ASN1ObjectIdentifier type : extTypes) {
        extControl = controls.remove(type);
        boolean addMe = addMe(type, extControl, neededExtTypes, wantedExtTypes);
        if (addMe) {
            ExtensionValue value = null;
            if (requestedExtensions != null && extControl.isRequest()) {
                Extension reqExt = requestedExtensions.getExtension(type);
                if (reqExt != null) {
                    value = new ExtensionValue(reqExt.isCritical(), reqExt.getParsedValue());
                }
            }
            if (value == null) {
                value = subvalues.getExtensionValue(type);
            }
            addExtension(values, type, value, extControl, neededExtTypes, wantedExtTypes);
        }
    }
    Set<ASN1ObjectIdentifier> unprocessedExtTypes = new HashSet<>();
    for (ASN1ObjectIdentifier type : controls.keySet()) {
        if (controls.get(type).isRequired()) {
            unprocessedExtTypes.add(type);
        }
    }
    if (CollectionUtil.isNonEmpty(unprocessedExtTypes)) {
        throw new CertprofileException("could not add required extensions " + toString(unprocessedExtTypes));
    }
    if (CollectionUtil.isNonEmpty(neededExtTypes)) {
        throw new BadCertTemplateException("could not add requested extensions " + toString(neededExtTypes));
    }
    return values;
}
Also used : AuthorityInformationAccess(org.bouncycastle.asn1.x509.AuthorityInformationAccess) AuthorityInfoAccessControl(org.xipki.ca.api.profile.x509.AuthorityInfoAccessControl) HashMap(java.util.HashMap) ExtendedKeyUsage(org.bouncycastle.asn1.x509.ExtendedKeyUsage) KeyUsage(org.xipki.security.KeyUsage) KeyUsageControl(org.xipki.ca.api.profile.x509.KeyUsageControl) ExtKeyUsageControl(org.xipki.ca.api.profile.x509.ExtKeyUsageControl) AuthorityKeyIdentifier(org.bouncycastle.asn1.x509.AuthorityKeyIdentifier) X500Name(org.bouncycastle.asn1.x500.X500Name) ExtensionValue(org.xipki.ca.api.profile.ExtensionValue) DERNull(org.bouncycastle.asn1.DERNull) CertprofileException(org.xipki.ca.api.profile.CertprofileException) ExtensionControl(org.xipki.ca.api.profile.ExtensionControl) ExtensionValues(org.xipki.ca.api.profile.ExtensionValues) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) ExtendedKeyUsage(org.bouncycastle.asn1.x509.ExtendedKeyUsage) HashSet(java.util.HashSet) ExtKeyUsageControl(org.xipki.ca.api.profile.x509.ExtKeyUsageControl) SubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectKeyIdentifier) LinkedList(java.util.LinkedList) Extension(org.bouncycastle.asn1.x509.Extension) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) ExtensionExistence(org.xipki.security.ExtensionExistence) BadCertTemplateException(org.xipki.ca.api.BadCertTemplateException) GeneralName(org.bouncycastle.asn1.x509.GeneralName) BasicConstraints(org.bouncycastle.asn1.x509.BasicConstraints) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 9 with SubjectKeyIdentifier

use of org.bouncycastle.asn1.x509.SubjectKeyIdentifier in project credhub by cloudfoundry-incubator.

the class CertificateGenerateTest method certificateGeneration_shouldGenerateCorrectCertificate.

@Test
public void certificateGeneration_shouldGenerateCorrectCertificate() throws Exception {
    MockHttpServletRequestBuilder caPost = post("/api/v1/data").header("Authorization", "Bearer " + UAA_OAUTH2_PASSWORD_GRANT_TOKEN).accept(APPLICATION_JSON).contentType(APPLICATION_JSON).content("{\n" + "  \"name\" : \"picard\",\n" + "  \"type\" : \"certificate\",\n" + "  \"parameters\" : {\n" + "    \"common_name\" : \"federation\",\n" + "    \"is_ca\" : true,\n" + "    \"self_sign\" : true\n" + "  }\n" + "}");
    String caResult = this.mockMvc.perform(caPost).andDo(print()).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
    String picardCert = (new JSONObject(caResult)).getJSONObject("value").getString("certificate");
    String picardCA = (new JSONObject(caResult)).getJSONObject("value").getString("ca");
    assertThat(picardCert, equalTo(picardCA));
    assertThat(picardCert, notNullValue());
    MockHttpServletRequestBuilder certPost = post("/api/v1/data").header("Authorization", "Bearer " + UAA_OAUTH2_PASSWORD_GRANT_TOKEN).accept(APPLICATION_JSON).contentType(APPLICATION_JSON).content("{\n" + "  \"name\" : \"riker\",\n" + "  \"type\" : \"certificate\",\n" + "  \"parameters\" : {\n" + "    \"common_name\" : \"federation\",\n" + "    \"ca\" : \"picard\"\n" + "  }\n" + "}");
    String certResult = this.mockMvc.perform(certPost).andDo(print()).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
    String certCa = (new JSONObject(certResult)).getJSONObject("value").getString("ca");
    String cert = (new JSONObject(certResult)).getJSONObject("value").getString("certificate");
    assertThat(certCa, equalTo(picardCert));
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    X509Certificate caPem = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(picardCert.getBytes()));
    X509Certificate certPem = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(cert.getBytes()));
    byte[] subjectKeyIdDer = caPem.getExtensionValue(Extension.subjectKeyIdentifier.getId());
    SubjectKeyIdentifier subjectKeyIdentifier = SubjectKeyIdentifier.getInstance(JcaX509ExtensionUtils.parseExtensionValue(subjectKeyIdDer));
    byte[] subjectKeyId = subjectKeyIdentifier.getKeyIdentifier();
    byte[] authorityKeyIdDer = certPem.getExtensionValue(Extension.authorityKeyIdentifier.getId());
    AuthorityKeyIdentifier authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(JcaX509ExtensionUtils.parseExtensionValue(authorityKeyIdDer));
    byte[] authKeyId = authorityKeyIdentifier.getKeyIdentifier();
    assertThat(subjectKeyId, equalTo(authKeyId));
}
Also used : JSONObject(org.json.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) MockHttpServletRequestBuilder(org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder) AuthorityKeyIdentifier(org.bouncycastle.asn1.x509.AuthorityKeyIdentifier) SubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectKeyIdentifier) CertificateFactory(java.security.cert.CertificateFactory) X509Certificate(java.security.cert.X509Certificate) Test(org.junit.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest)

Example 10 with SubjectKeyIdentifier

use of org.bouncycastle.asn1.x509.SubjectKeyIdentifier 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)

Aggregations

SubjectKeyIdentifier (org.bouncycastle.asn1.x509.SubjectKeyIdentifier)18 X509Certificate (java.security.cert.X509Certificate)9 IOException (java.io.IOException)7 BasicConstraints (org.bouncycastle.asn1.x509.BasicConstraints)7 CertificateException (java.security.cert.CertificateException)6 GeneralName (org.bouncycastle.asn1.x509.GeneralName)6 ByteArrayInputStream (java.io.ByteArrayInputStream)5 Date (java.util.Date)5 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)5 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)5 AuthorityKeyIdentifier (org.bouncycastle.asn1.x509.AuthorityKeyIdentifier)5 GeneralNames (org.bouncycastle.asn1.x509.GeneralNames)5 BigInteger (java.math.BigInteger)4 KeyPair (java.security.KeyPair)4 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)4 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)4 X500Name (org.bouncycastle.asn1.x500.X500Name)4 Extension (org.bouncycastle.asn1.x509.Extension)4 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)4 X509v3CertificateBuilder (org.bouncycastle.cert.X509v3CertificateBuilder)4