Search in sources :

Example 76 with Extensions

use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.

the class CmpAgent method buildRevokeCertRequest.

// method buildCertConfirmRequest
private PKIMessage buildRevokeCertRequest(RevokeCertRequest request) throws CmpClientException {
    PKIHeader header = buildPkiHeader(null);
    List<RevokeCertRequest.Entry> requestEntries = request.getRequestEntries();
    List<RevDetails> revDetailsArray = new ArrayList<>(requestEntries.size());
    for (RevokeCertRequest.Entry requestEntry : requestEntries) {
        CertTemplateBuilder certTempBuilder = new CertTemplateBuilder();
        certTempBuilder.setIssuer(requestEntry.getIssuer());
        certTempBuilder.setSerialNumber(new ASN1Integer(requestEntry.getSerialNumber()));
        byte[] aki = requestEntry.getAuthorityKeyIdentifier();
        if (aki != null) {
            Extensions certTempExts = getCertTempExtensions(aki);
            certTempBuilder.setExtensions(certTempExts);
        }
        Date invalidityDate = requestEntry.getInvalidityDate();
        int idx = (invalidityDate == null) ? 1 : 2;
        Extension[] extensions = new Extension[idx];
        try {
            ASN1Enumerated reason = new ASN1Enumerated(requestEntry.getReason());
            extensions[0] = new Extension(Extension.reasonCode, true, new DEROctetString(reason.getEncoded()));
            if (invalidityDate != null) {
                ASN1GeneralizedTime time = new ASN1GeneralizedTime(invalidityDate);
                extensions[1] = new Extension(Extension.invalidityDate, true, new DEROctetString(time.getEncoded()));
            }
        } catch (IOException ex) {
            throw new CmpClientException(ex.getMessage(), ex);
        }
        Extensions exts = new Extensions(extensions);
        RevDetails revDetails = new RevDetails(certTempBuilder.build(), exts);
        revDetailsArray.add(revDetails);
    }
    RevReqContent content = new RevReqContent(revDetailsArray.toArray(new RevDetails[0]));
    PKIBody body = new PKIBody(PKIBody.TYPE_REVOCATION_REQ, content);
    return new PKIMessage(header, body);
}
Also used : IOException(java.io.IOException) Extensions(org.bouncycastle.asn1.x509.Extensions) Extension(org.bouncycastle.asn1.x509.Extension) Entry(java.util.Map.Entry) CertTemplateBuilder(org.bouncycastle.asn1.crmf.CertTemplateBuilder)

Example 77 with Extensions

use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.

the class X509Util method getCoreExtValue.

public static byte[] getCoreExtValue(Extensions extensions, ASN1ObjectIdentifier extnType) {
    notNull(extensions, "extensions");
    notNull(extnType, "extnType");
    Extension extn = extensions.getExtension(extnType);
    if (extn == null) {
        return null;
    }
    return extn.getExtnValue().getOctets();
}
Also used : Extension(org.bouncycastle.asn1.x509.Extension)

Example 78 with Extensions

use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.

the class RestResponder method service.

public RestResponse service(String path, AuditEvent event, byte[] request, HttpRequestMetadataRetriever httpRetriever) {
    event.setApplicationName(APPNAME);
    event.setName(NAME_perf);
    event.addEventData(NAME_req_type, RequestType.REST.name());
    String msgId = RandomUtil.nextHexLong();
    event.addEventData(NAME_mid, msgId);
    AuditLevel auditLevel = AuditLevel.INFO;
    AuditStatus auditStatus = AuditStatus.SUCCESSFUL;
    String auditMessage = null;
    try {
        if (responderManager == null) {
            String message = "responderManager in servlet not configured";
            LOG.error(message);
            throw new HttpRespAuditException(INTERNAL_SERVER_ERROR, message, ERROR, FAILED);
        }
        String caName = null;
        String command = null;
        X509Ca ca = null;
        if (path.length() > 1) {
            // the first char is always '/'
            String coreUri = path;
            int sepIndex = coreUri.indexOf('/', 1);
            if (sepIndex == -1 || sepIndex == coreUri.length() - 1) {
                String message = "invalid path " + path;
                LOG.error(message);
                throw new HttpRespAuditException(NOT_FOUND, message, ERROR, FAILED);
            }
            // skip also the first char ('/')
            String caAlias = coreUri.substring(1, sepIndex).toLowerCase();
            command = coreUri.substring(sepIndex + 1).toLowerCase();
            caName = responderManager.getCaNameForAlias(caAlias);
            if (caName == null) {
                caName = caAlias;
            }
            CmpResponder caResponder = responderManager.getX509CaResponder(caName);
            if (caResponder != null) {
                ca = caResponder.getCa();
            }
        }
        if (StringUtil.isBlank(command)) {
            String message = "command is not specified";
            LOG.warn(message);
            throw new HttpRespAuditException(NOT_FOUND, message, INFO, FAILED);
        }
        if (ca == null || !ca.getCaInfo().supportsRest() || ca.getCaInfo().getStatus() != CaStatus.ACTIVE) {
            String message;
            if (ca == null) {
                message = "unknown CA '" + caName + "'";
            } else if (!ca.getCaInfo().supportsRest()) {
                message = "REST is not supported by the CA '" + caName + "'";
            } else {
                message = "CA '" + caName + "' is out of service";
            }
            LOG.warn(message);
            throw new HttpRespAuditException(NOT_FOUND, message, INFO, FAILED);
        }
        event.addEventData(NAME_ca, ca.getCaIdent().getName());
        event.addEventType(command);
        RequestorInfo requestor;
        // Retrieve the user:password
        String hdrValue = httpRetriever.getHeader("Authorization");
        if (hdrValue != null && hdrValue.startsWith("Basic ")) {
            String user = null;
            byte[] password = null;
            if (hdrValue.length() > 6) {
                String b64 = hdrValue.substring(6);
                byte[] userPwd = Base64.decodeFast(b64);
                int idx = -1;
                for (int i = 0; i < userPwd.length; i++) {
                    if (userPwd[i] == ':') {
                        idx = i;
                        break;
                    }
                }
                if (idx != -1 && idx < userPwd.length - 1) {
                    user = StringUtil.toUtf8String(Arrays.copyOfRange(userPwd, 0, idx));
                    password = Arrays.copyOfRange(userPwd, idx + 1, userPwd.length);
                }
            }
            if (user == null) {
                throw new HttpRespAuditException(UNAUTHORIZED, "invalid Authorization information", INFO, FAILED);
            }
            NameId userIdent = ca.authenticateUser(user, password);
            if (userIdent == null) {
                throw new HttpRespAuditException(UNAUTHORIZED, "could not authenticate user", INFO, FAILED);
            }
            requestor = ca.getByUserRequestor(userIdent);
        } else {
            X509Cert clientCert = httpRetriever.getTlsClientCert();
            if (clientCert == null) {
                throw new HttpRespAuditException(UNAUTHORIZED, "no client certificate", INFO, FAILED);
            }
            requestor = ca.getRequestor(clientCert);
        }
        if (requestor == null) {
            throw new OperationException(NOT_PERMITTED, "no requestor specified");
        }
        event.addEventData(NAME_requestor, requestor.getIdent().getName());
        String respCt = null;
        byte[] respBytes = null;
        switch(command) {
            case CMD_cacert:
                {
                    respCt = CT_pkix_cert;
                    respBytes = ca.getCaInfo().getCert().getEncoded();
                    break;
                }
            case CMD_pop_dh_certs:
                {
                    PopControl control = responderManager.getX509Ca(caName).getCaInfo().getPopControl();
                    respBytes = new byte[0];
                    if (control != null) {
                        X509Cert[] dhCerts = control.getDhCertificates();
                        if (dhCerts != null) {
                            respCt = CT_pem_file;
                            respBytes = StringUtil.toUtf8Bytes(X509Util.encodeCertificates(dhCerts));
                        }
                    }
                    break;
                }
            case CMD_cacertchain:
                {
                    respCt = CT_pem_file;
                    List<X509Cert> certchain = ca.getCaInfo().getCertchain();
                    int size = 1 + (certchain == null ? 0 : certchain.size());
                    X509Cert[] certchainWithCaCert = new X509Cert[size];
                    certchainWithCaCert[0] = ca.getCaInfo().getCert();
                    if (size > 1) {
                        for (int i = 1; i < size; i++) {
                            certchainWithCaCert[i] = certchain.get(i - 1);
                        }
                    }
                    respBytes = StringUtil.toUtf8Bytes(X509Util.encodeCertificates(certchainWithCaCert));
                    break;
                }
            case CMD_enroll_cert:
            case CMD_enroll_cert_cagenkeypair:
                {
                    String profile = httpRetriever.getParameter(PARAM_profile);
                    if (StringUtil.isBlank(profile)) {
                        throw new HttpRespAuditException(BAD_REQUEST, "required parameter " + PARAM_profile + " not specified", INFO, FAILED);
                    }
                    profile = profile.toLowerCase();
                    try {
                        requestor.assertPermitted(PermissionConstants.ENROLL_CERT);
                    } catch (InsufficientPermissionException ex) {
                        throw new OperationException(NOT_PERMITTED, ex.getMessage());
                    }
                    if (!requestor.isCertprofilePermitted(profile)) {
                        throw new OperationException(NOT_PERMITTED, "certprofile " + profile + " is not allowed");
                    }
                    String strNotBefore = httpRetriever.getParameter(PARAM_not_before);
                    Date notBefore = (strNotBefore == null) ? null : DateUtil.parseUtcTimeyyyyMMddhhmmss(strNotBefore);
                    String strNotAfter = httpRetriever.getParameter(PARAM_not_after);
                    Date notAfter = (strNotAfter == null) ? null : DateUtil.parseUtcTimeyyyyMMddhhmmss(strNotAfter);
                    if (CMD_enroll_cert_cagenkeypair.equals(command)) {
                        String ct = httpRetriever.getHeader("Content-Type");
                        X500Name subject;
                        Extensions extensions;
                        if (ct.startsWith("text/plain")) {
                            Properties props = new Properties();
                            props.load(new ByteArrayInputStream(request));
                            String strSubject = props.getProperty("subject");
                            if (strSubject == null) {
                                throw new OperationException(BAD_CERT_TEMPLATE, "subject is not specified");
                            }
                            try {
                                subject = new X500Name(strSubject);
                            } catch (Exception ex) {
                                throw new OperationException(BAD_CERT_TEMPLATE, "invalid subject");
                            }
                            extensions = null;
                        } else if (CT_pkcs10.equalsIgnoreCase(ct)) {
                            // some clients may send the PEM encoded CSR.
                            request = X509Util.toDerEncoded(request);
                            // The PKCS#10 will only be used for transport of subject and extensions.
                            // The associated key will not be used, so the verification of POP is skipped.
                            CertificationRequestInfo certTemp = CertificationRequest.getInstance(request).getCertificationRequestInfo();
                            subject = certTemp.getSubject();
                            extensions = CaUtil.getExtensions(certTemp);
                        } else {
                            String message = "unsupported media type " + ct;
                            throw new HttpRespAuditException(UNSUPPORTED_MEDIA_TYPE, message, INFO, FAILED);
                        }
                        CertTemplateData certTemplate = new CertTemplateData(subject, null, notBefore, notAfter, extensions, profile, null, true);
                        CertificateInfo certInfo = ca.generateCert(certTemplate, requestor, RequestType.REST, null, msgId);
                        if (ca.getCaInfo().isSaveRequest()) {
                            long dbId = ca.addRequest(request);
                            ca.addRequestCert(dbId, certInfo.getCert().getCertId());
                        }
                        respCt = CT_pem_file;
                        byte[] keyBytes = PemEncoder.encode(certInfo.getPrivateKey().getEncoded(), PemLabel.PRIVATE_KEY);
                        byte[] certBytes = PemEncoder.encode(certInfo.getCert().getCert().getEncoded(), PemLabel.CERTIFICATE);
                        respBytes = new byte[keyBytes.length + 2 + certBytes.length];
                        System.arraycopy(keyBytes, 0, respBytes, 0, keyBytes.length);
                        respBytes[keyBytes.length] = '\r';
                        respBytes[keyBytes.length + 1] = '\n';
                        System.arraycopy(certBytes, 0, respBytes, keyBytes.length + 2, certBytes.length);
                    } else {
                        String ct = httpRetriever.getHeader("Content-Type");
                        if (!CT_pkcs10.equalsIgnoreCase(ct)) {
                            String message = "unsupported media type " + ct;
                            throw new HttpRespAuditException(UNSUPPORTED_MEDIA_TYPE, message, INFO, FAILED);
                        }
                        CertificationRequest csr = CertificationRequest.getInstance(request);
                        if (!ca.verifyCsr(csr)) {
                            throw new OperationException(BAD_POP);
                        }
                        CertificationRequestInfo certTemp = csr.getCertificationRequestInfo();
                        X500Name subject = certTemp.getSubject();
                        SubjectPublicKeyInfo publicKeyInfo = certTemp.getSubjectPublicKeyInfo();
                        Extensions extensions = CaUtil.getExtensions(certTemp);
                        CertTemplateData certTemplate = new CertTemplateData(subject, publicKeyInfo, notBefore, notAfter, extensions, profile);
                        CertificateInfo certInfo = ca.generateCert(certTemplate, requestor, RequestType.REST, null, msgId);
                        if (ca.getCaInfo().isSaveRequest()) {
                            long dbId = ca.addRequest(request);
                            ca.addRequestCert(dbId, certInfo.getCert().getCertId());
                        }
                        CertWithDbId cert = certInfo.getCert();
                        if (cert == null) {
                            String message = "could not generate certificate";
                            LOG.warn(message);
                            throw new HttpRespAuditException(INTERNAL_SERVER_ERROR, message, INFO, FAILED);
                        }
                        respCt = CT_pkix_cert;
                        respBytes = cert.getCert().getEncoded();
                    }
                    break;
                }
            case CMD_revoke_cert:
            case CMD_delete_cert:
                {
                    int permission;
                    if (CMD_revoke_cert.equals(command)) {
                        permission = PermissionConstants.REVOKE_CERT;
                    } else {
                        permission = PermissionConstants.REMOVE_CERT;
                    }
                    try {
                        requestor.assertPermitted(permission);
                    } catch (InsufficientPermissionException ex) {
                        throw new OperationException(NOT_PERMITTED, ex.getMessage());
                    }
                    String strCaSha1 = httpRetriever.getParameter(PARAM_ca_sha1);
                    if (StringUtil.isBlank(strCaSha1)) {
                        throw new HttpRespAuditException(BAD_REQUEST, "required parameter " + PARAM_ca_sha1 + " not specified", INFO, FAILED);
                    }
                    String strSerialNumber = httpRetriever.getParameter(PARAM_serial_number);
                    if (StringUtil.isBlank(strSerialNumber)) {
                        throw new HttpRespAuditException(BAD_REQUEST, "required parameter " + PARAM_serial_number + " not specified", INFO, FAILED);
                    }
                    if (!strCaSha1.equalsIgnoreCase(ca.getHexSha1OfCert())) {
                        throw new HttpRespAuditException(BAD_REQUEST, "unknown " + PARAM_ca_sha1, INFO, FAILED);
                    }
                    BigInteger serialNumber;
                    try {
                        serialNumber = toBigInt(strSerialNumber);
                    } catch (NumberFormatException ex) {
                        throw new OperationException(ErrorCode.BAD_REQUEST, ex.getMessage());
                    }
                    if (CMD_revoke_cert.equals(command)) {
                        String strReason = httpRetriever.getParameter(PARAM_reason);
                        CrlReason reason = (strReason == null) ? CrlReason.UNSPECIFIED : CrlReason.forNameOrText(strReason);
                        if (reason == CrlReason.REMOVE_FROM_CRL) {
                            ca.unrevokeCert(serialNumber, msgId);
                        } else {
                            Date invalidityTime = null;
                            String strInvalidityTime = httpRetriever.getParameter(PARAM_invalidity_time);
                            if (StringUtil.isNotBlank(strInvalidityTime)) {
                                invalidityTime = DateUtil.parseUtcTimeyyyyMMddhhmmss(strInvalidityTime);
                            }
                            ca.revokeCert(serialNumber, reason, invalidityTime, msgId);
                        }
                    } else {
                        // if (CMD_delete_cert.equals(command)) {
                        ca.removeCert(serialNumber, msgId);
                    }
                    break;
                }
            case CMD_crl:
                {
                    try {
                        requestor.assertPermitted(PermissionConstants.GET_CRL);
                    } catch (InsufficientPermissionException ex) {
                        throw new OperationException(NOT_PERMITTED, ex.getMessage());
                    }
                    String strCrlNumber = httpRetriever.getParameter(PARAM_crl_number);
                    BigInteger crlNumber = null;
                    if (StringUtil.isNotBlank(strCrlNumber)) {
                        try {
                            crlNumber = toBigInt(strCrlNumber);
                        } catch (NumberFormatException ex) {
                            String message = "invalid crlNumber '" + strCrlNumber + "'";
                            LOG.warn(message);
                            throw new HttpRespAuditException(BAD_REQUEST, message, INFO, FAILED);
                        }
                    }
                    X509CRLHolder crl = ca.getCrl(crlNumber, msgId);
                    if (crl == null) {
                        String message = "could not get CRL";
                        LOG.warn(message);
                        throw new HttpRespAuditException(INTERNAL_SERVER_ERROR, message, INFO, FAILED);
                    }
                    respCt = CT_pkix_crl;
                    respBytes = crl.getEncoded();
                    break;
                }
            case CMD_new_crl:
                {
                    try {
                        requestor.assertPermitted(PermissionConstants.GEN_CRL);
                    } catch (InsufficientPermissionException ex) {
                        throw new OperationException(NOT_PERMITTED, ex.getMessage());
                    }
                    X509CRLHolder crl = ca.generateCrlOnDemand(msgId);
                    respCt = CT_pkix_crl;
                    respBytes = crl.getEncoded();
                    break;
                }
            default:
                {
                    String message = "invalid command '" + command + "'";
                    LOG.error(message);
                    throw new HttpRespAuditException(NOT_FOUND, message, INFO, FAILED);
                }
        }
        Map<String, String> headers = new HashMap<>();
        headers.put(HEADER_PKISTATUS, PKISTATUS_accepted);
        return new RestResponse(OK, respCt, headers, respBytes);
    } catch (OperationException ex) {
        ErrorCode code = ex.getErrorCode();
        if (LOG.isWarnEnabled()) {
            String msg = StringUtil.concat("generate certificate, OperationException: code=", code.name(), ", message=", ex.getErrorMessage());
            LogUtil.warn(LOG, ex, msg);
        }
        int sc;
        String failureInfo;
        switch(code) {
            case ALREADY_ISSUED:
                sc = BAD_REQUEST;
                failureInfo = FAILINFO_badRequest;
                break;
            case BAD_CERT_TEMPLATE:
                sc = BAD_REQUEST;
                failureInfo = FAILINFO_badCertTemplate;
                break;
            case BAD_REQUEST:
                sc = BAD_REQUEST;
                failureInfo = FAILINFO_badRequest;
                break;
            case CERT_REVOKED:
                sc = CONFLICT;
                failureInfo = FAILINFO_certRevoked;
                break;
            case CRL_FAILURE:
                sc = INTERNAL_SERVER_ERROR;
                failureInfo = FAILINFO_systemFailure;
                break;
            case DATABASE_FAILURE:
                sc = INTERNAL_SERVER_ERROR;
                failureInfo = FAILINFO_systemFailure;
                break;
            case NOT_PERMITTED:
                sc = UNAUTHORIZED;
                failureInfo = FAILINFO_notAuthorized;
                break;
            case INVALID_EXTENSION:
                sc = BAD_REQUEST;
                failureInfo = FAILINFO_badRequest;
                break;
            case SYSTEM_FAILURE:
                sc = INTERNAL_SERVER_ERROR;
                failureInfo = FAILINFO_systemFailure;
                break;
            case SYSTEM_UNAVAILABLE:
                sc = SERVICE_UNAVAILABLE;
                failureInfo = FAILINFO_systemUnavail;
                break;
            case UNKNOWN_CERT:
                sc = BAD_REQUEST;
                failureInfo = FAILINFO_badCertId;
                break;
            case UNKNOWN_CERT_PROFILE:
                sc = BAD_REQUEST;
                failureInfo = FAILINFO_badCertTemplate;
                break;
            default:
                sc = INTERNAL_SERVER_ERROR;
                failureInfo = FAILINFO_systemFailure;
                break;
        }
        // end switch (code)
        event.setStatus(AuditStatus.FAILED);
        event.addEventData(NAME_message, code.name());
        switch(code) {
            case DATABASE_FAILURE:
            case SYSTEM_FAILURE:
                auditMessage = code.name();
                break;
            default:
                auditMessage = code.name() + ": " + ex.getErrorMessage();
                break;
        }
        // end switch code
        Map<String, String> headers = new HashMap<>();
        headers.put(HEADER_PKISTATUS, PKISTATUS_rejection);
        if (StringUtil.isNotBlank(failureInfo)) {
            headers.put(HEADER_failInfo, failureInfo);
        }
        return new RestResponse(sc, null, headers, null);
    } catch (HttpRespAuditException ex) {
        auditStatus = ex.getAuditStatus();
        auditLevel = ex.getAuditLevel();
        auditMessage = ex.getAuditMessage();
        return new RestResponse(ex.getHttpStatus(), null, null, null);
    } catch (Throwable th) {
        if (th instanceof EOFException) {
            LogUtil.warn(LOG, th, "connection reset by peer");
        } else {
            LOG.error("Throwable thrown, this should not happen!", th);
        }
        auditLevel = AuditLevel.ERROR;
        auditStatus = AuditStatus.FAILED;
        auditMessage = "internal error";
        return new RestResponse(INTERNAL_SERVER_ERROR, null, null, null);
    } finally {
        event.setStatus(auditStatus);
        event.setLevel(auditLevel);
        if (auditMessage != null) {
            event.addEventData(NAME_message, auditMessage);
        }
    }
}
Also used : CertificationRequestInfo(org.bouncycastle.asn1.pkcs.CertificationRequestInfo) X500Name(org.bouncycastle.asn1.x500.X500Name) Extensions(org.bouncycastle.asn1.x509.Extensions) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) X509Cert(org.xipki.security.X509Cert) EOFException(java.io.EOFException) CrlReason(org.xipki.security.CrlReason) CmpResponder(org.xipki.ca.server.cmp.CmpResponder) AuditLevel(org.xipki.audit.AuditLevel) EOFException(java.io.EOFException) AuditStatus(org.xipki.audit.AuditStatus) ByteArrayInputStream(java.io.ByteArrayInputStream) X509CRLHolder(org.bouncycastle.cert.X509CRLHolder) BigInteger(java.math.BigInteger) ErrorCode(org.xipki.ca.api.OperationException.ErrorCode) RequestorInfo(org.xipki.ca.api.mgmt.RequestorInfo) CertificationRequest(org.bouncycastle.asn1.pkcs.CertificationRequest) PopControl(org.xipki.ca.api.mgmt.PopControl)

Example 79 with Extensions

use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.

the class ExtensionsChecker method checkExtensions.

public List<ValidationIssue> checkExtensions(Certificate cert, IssuerInfo issuerInfo, Extensions requestedExtns, X500Name requestedSubject) {
    notNull(cert, "cert");
    notNull(issuerInfo, "issuerInfo");
    X509Cert jceCert = new X509Cert(cert);
    List<ValidationIssue> result = new LinkedList<>();
    // detect the list of extension types in certificate
    Set<ASN1ObjectIdentifier> presentExtenionTypes = getExensionTypes(cert, issuerInfo, requestedExtns);
    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> extnControls = 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 extnControl = extnControls.get(oid);
        if (extnControl.isCritical() != ext.isCritical()) {
            addViolation(failureMsg, "critical", ext.isCritical(), extnControl.isCritical());
        }
        byte[] extnValue = ext.getExtnValue().getOctets();
        try {
            if (extensionSyntaxes != null && extensionSyntaxes.containsKey(oid)) {
                Extension requestedExtn = requestedExtns.getExtension(oid);
                if (!Arrays.equals(requestedExtn.getExtnValue().getOctets(), extnValue)) {
                    failureMsg.append("extension in certificate does not equal the one contained in the request");
                } else {
                    ExtnSyntax syntax = extensionSyntaxes.get(oid);
                    String extnName = "extension " + ObjectIdentifiers.oidToDisplayName(oid);
                    try {
                        ExtensionSyntaxChecker.checkExtension(extnName, ext.getParsedValue(), syntax);
                    } catch (BadCertTemplateException ex) {
                        failureMsg.append(ex.getMessage());
                    }
                }
            } else if (Extension.authorityKeyIdentifier.equals(oid)) {
                a2gChecker.checkExtnAuthorityKeyId(failureMsg, extnValue, issuerInfo);
            } else if (Extension.subjectKeyIdentifier.equals(oid)) {
                // SubjectKeyIdentifier
                o2tChecker.checkExtnSubjectKeyIdentifier(failureMsg, extnValue, cert.getSubjectPublicKeyInfo());
            } else if (Extension.keyUsage.equals(oid)) {
                h2nChecker.checkExtnKeyUsage(failureMsg, jceCert.getKeyUsage(), requestedExtns, extnControl);
            } else if (Extension.certificatePolicies.equals(oid)) {
                a2gChecker.checkExtnCertificatePolicies(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.policyMappings.equals(oid)) {
                o2tChecker.checkExtnPolicyMappings(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.subjectAlternativeName.equals(oid)) {
                o2tChecker.checkExtnSubjectAltNames(failureMsg, extnValue, requestedExtns, extnControl, requestedSubject);
            } else if (Extension.subjectDirectoryAttributes.equals(oid)) {
                o2tChecker.checkExtnSubjectDirAttrs(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.issuerAlternativeName.equals(oid)) {
                h2nChecker.checkExtnIssuerAltNames(failureMsg, extnValue, issuerInfo);
            } else if (Extension.basicConstraints.equals(oid)) {
                a2gChecker.checkExtnBasicConstraints(failureMsg, extnValue);
            } else if (Extension.nameConstraints.equals(oid)) {
                h2nChecker.checkExtnNameConstraints(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.policyConstraints.equals(oid)) {
                o2tChecker.checkExtnPolicyConstraints(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.extendedKeyUsage.equals(oid)) {
                a2gChecker.checkExtnExtendedKeyUsage(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.cRLDistributionPoints.equals(oid)) {
                a2gChecker.checkExtnCrlDistributionPoints(failureMsg, extnValue, issuerInfo);
            } else if (Extension.inhibitAnyPolicy.equals(oid)) {
                h2nChecker.checkExtnInhibitAnyPolicy(failureMsg, extnValue, extensions, extnControl);
            } else if (Extension.freshestCRL.equals(oid)) {
                a2gChecker.checkExtnDeltaCrlDistributionPoints(failureMsg, extnValue, issuerInfo);
            } else if (Extension.authorityInfoAccess.equals(oid)) {
                a2gChecker.checkExtnAuthorityInfoAccess(failureMsg, extnValue, issuerInfo);
            } else if (Extension.subjectInfoAccess.equals(oid)) {
                o2tChecker.checkExtnSubjectInfoAccess(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extn.id_extension_admission.equals(oid)) {
                a2gChecker.checkExtnAdmission(failureMsg, extnValue, requestedExtns, requestedSubject, extnControl);
            } else if (Extn.id_extension_pkix_ocsp_nocheck.equals(oid)) {
                o2tChecker.checkExtnOcspNocheck(failureMsg, extnValue);
            } else if (Extn.id_extension_restriction.equals(oid)) {
                o2tChecker.checkExtnRestriction(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extn.id_extension_additionalInformation.equals(oid)) {
                a2gChecker.checkExtnAdditionalInformation(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extn.id_extension_validityModel.equals(oid)) {
                u2zChecker.checkExtnValidityModel(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.privateKeyUsagePeriod.equals(oid)) {
                o2tChecker.checkExtnPrivateKeyUsagePeriod(failureMsg, extnValue, jceCert.getNotBefore(), jceCert.getNotAfter());
            } else if (Extension.qCStatements.equals(oid)) {
                o2tChecker.checkExtnQcStatements(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extension.biometricInfo.equals(oid)) {
                a2gChecker.checkExtnBiometricInfo(failureMsg, extnValue, requestedExtns);
            } else if (Extn.id_pe_tlsfeature.equals(oid)) {
                o2tChecker.checkExtnTlsFeature(failureMsg, extnValue, requestedExtns, extnControl);
            } else if (Extn.id_smimeCapabilities.equals(oid)) {
                o2tChecker.checkSmimeCapabilities(failureMsg, extnValue, extnControl);
            } else if (Extn.id_SCTs.equals(oid)) {
                o2tChecker.checkScts(failureMsg, extnValue, extnControl);
            } else if (Extn.id_GMT_0015_ICRegistrationNumber.equals(oid) || Extn.id_GMT_0015_InsuranceNumber.equals(oid) || Extn.id_GMT_0015_OrganizationCode.equals(oid) || Extn.id_GMT_0015_TaxationNumber.equals(oid) || Extn.id_GMT_0015_IdentityCode.equals(oid)) {
                a2gChecker.checkExtnGmt0015(failureMsg, extnValue, requestedExtns, extnControl, oid, requestedSubject);
            } else {
                byte[] expected = getExpectedExtValue(oid, requestedExtns, extnControl);
                if (!Arrays.equals(expected, extnValue)) {
                    addViolation(failureMsg, "extension value", hex(extnValue), (expected == null) ? "not present" : hex(expected));
                }
            }
            if (failureMsg.length() > 0) {
                issue.setFailureMessage(failureMsg.toString());
            }
        } catch (IllegalArgumentException | ClassCastException | IOException | 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 : IOException(java.io.IOException) Extensions(org.bouncycastle.asn1.x509.Extensions) ValidationIssue(org.xipki.qa.ValidationIssue) Extension(org.bouncycastle.asn1.x509.Extension) X509Cert(org.xipki.security.X509Cert) ExtensionControl(org.xipki.ca.api.profile.Certprofile.ExtensionControl) BadCertTemplateException(org.xipki.ca.api.BadCertTemplateException)

Example 80 with Extensions

use of com.github.zhenwei.core.asn1.x509.Extensions in project xipki by xipki.

the class H2nChecker method checkExtnKeyUsage.

// method checkExtnIssuerAltNames
void checkExtnKeyUsage(StringBuilder failureMsg, boolean[] usages, Extensions requestedExtns, ExtensionControl extnControl) {
    int len = usages.length;
    if (len > 9) {
        failureMsg.append("invalid syntax: size of valid bits is larger than 9: ").append(len);
        failureMsg.append("; ");
    }
    Set<String> isUsages = new HashSet<>();
    for (int i = 0; i < len; i++) {
        if (usages[i]) {
            isUsages.add(ALL_USAGES.get(i));
        }
    }
    Set<String> expectedUsages = new HashSet<>();
    Set<KeyUsageControl> requiredKeyusage = getKeyusage(true);
    for (KeyUsageControl usage : requiredKeyusage) {
        expectedUsages.add(usage.getKeyUsage().getName());
    }
    Set<KeyUsageControl> optionalKeyusage = getKeyusage(false);
    if (requestedExtns != null && extnControl.isRequest() && isNotEmpty(optionalKeyusage)) {
        Extension extension = requestedExtns.getExtension(Extension.keyUsage);
        if (extension != null) {
            org.bouncycastle.asn1.x509.KeyUsage reqKeyUsage = org.bouncycastle.asn1.x509.KeyUsage.getInstance(extension.getParsedValue());
            for (KeyUsageControl k : optionalKeyusage) {
                if (reqKeyUsage.hasUsages(k.getKeyUsage().getBcUsage())) {
                    expectedUsages.add(k.getKeyUsage().getName());
                }
            }
        }
    }
    if (isEmpty(expectedUsages)) {
        byte[] constantExtValue = caller.getConstantExtensionValue(Extension.keyUsage);
        if (constantExtValue != null) {
            expectedUsages = getKeyUsage(constantExtValue);
        }
    }
    Set<String> diffs = CheckerUtil.strInBnotInA(expectedUsages, isUsages);
    if (isNotEmpty(diffs)) {
        failureMsg.append("usages ").append(diffs).append(" are present but not expected; ");
    }
    diffs = CheckerUtil.strInBnotInA(isUsages, expectedUsages);
    if (isNotEmpty(diffs)) {
        failureMsg.append("usages ").append(diffs).append(" are absent but are required; ");
    }
}
Also used : Extension(org.bouncycastle.asn1.x509.Extension) KeyUsageControl(org.xipki.ca.api.profile.Certprofile.KeyUsageControl) HashSet(java.util.HashSet)

Aggregations

Extensions (org.bouncycastle.asn1.x509.Extensions)113 Extension (org.bouncycastle.asn1.x509.Extension)89 IOException (java.io.IOException)72 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)67 Enumeration (java.util.Enumeration)57 HashSet (java.util.HashSet)49 DEROctetString (org.bouncycastle.asn1.DEROctetString)49 X500Name (org.bouncycastle.asn1.x500.X500Name)46 BigInteger (java.math.BigInteger)45 Set (java.util.Set)36 X509Certificate (java.security.cert.X509Certificate)35 Date (java.util.Date)35 GeneralName (org.bouncycastle.asn1.x509.GeneralName)35 ContentSigner (org.bouncycastle.operator.ContentSigner)32 JcaContentSignerBuilder (org.bouncycastle.operator.jcajce.JcaContentSignerBuilder)29 ASN1ObjectIdentifier (com.github.zhenwei.core.asn1.ASN1ObjectIdentifier)28 ArrayList (java.util.ArrayList)28 CertificateException (java.security.cert.CertificateException)27 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)27 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)27