Example usage for org.bouncycastle.asn1.x509 Extensions getExtensionParsedValue

List of usage examples for org.bouncycastle.asn1.x509 Extensions getExtensionParsedValue

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x509 Extensions getExtensionParsedValue.

Prototype

public ASN1Encodable getExtensionParsedValue(ASN1ObjectIdentifier oid) 

Source Link

Document

return the parsed value of the extension represented by the object identifier passed in.

Usage

From source file:org.apache.nifi.registry.security.util.CertificateUtils.java

License:Apache License

/**
 * Generates an issued {@link X509Certificate} from the given issuer certificate and {@link KeyPair}
 *
 * @param dn the distinguished name to use
 * @param publicKey the public key to issue the certificate to
 * @param extensions extensions extracted from the CSR
 * @param issuer the issuer's certificate
 * @param issuerKeyPair the issuer's keypair
 * @param signingAlgorithm the signing algorithm to use
 * @param days the number of days it should be valid for
 * @return an issued {@link X509Certificate} from the given issuer certificate and {@link KeyPair}
 * @throws CertificateException if there is an error issuing the certificate
 *//*from w  w w.  j  av  a 2 s  .c om*/
public static X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, Extensions extensions,
        X509Certificate issuer, KeyPair issuerKeyPair, String signingAlgorithm, int days)
        throws CertificateException {
    try {
        ContentSigner sigGen = new JcaContentSignerBuilder(signingAlgorithm)
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(issuerKeyPair.getPrivate());
        SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
        Date startDate = new Date();
        Date endDate = new Date(startDate.getTime() + TimeUnit.DAYS.toMillis(days));

        X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
                reverseX500Name(new X500Name(issuer.getSubjectX500Principal().getName())),
                getUniqueSerialNumber(), startDate, endDate, reverseX500Name(new X500Name(dn)), subPubKeyInfo);

        certBuilder.addExtension(Extension.subjectKeyIdentifier, false,
                new JcaX509ExtensionUtils().createSubjectKeyIdentifier(publicKey));

        certBuilder.addExtension(Extension.authorityKeyIdentifier, false,
                new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(issuerKeyPair.getPublic()));
        // Set certificate extensions
        // (1) digitalSignature extension
        certBuilder.addExtension(Extension.keyUsage, true,
                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment
                        | KeyUsage.keyAgreement | KeyUsage.nonRepudiation));

        certBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));

        // (2) extendedKeyUsage extension
        certBuilder.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(
                new KeyPurposeId[] { KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth }));

        // (3) subjectAlternativeName
        if (extensions != null && extensions.getExtension(Extension.subjectAlternativeName) != null) {
            certBuilder.addExtension(Extension.subjectAlternativeName, false,
                    extensions.getExtensionParsedValue(Extension.subjectAlternativeName));
        }

        X509CertificateHolder certificateHolder = certBuilder.build(sigGen);
        return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME)
                .getCertificate(certificateHolder);
    } catch (CertIOException | NoSuchAlgorithmException | OperatorCreationException e) {
        throw new CertificateException(e);
    }
}

From source file:org.xipki.ca.qa.impl.X509CertprofileQAImpl.java

License:Open Source License

private void checkExtensionSubjectAltName(final StringBuilder failureMsg, final byte[] extensionValue,
        final Extensions requestExtensions, final ExtensionControl extControl) {
    if (allowedSubjectAltNameModes == null) {
        byte[] expected = getExpectedExtValue(Extension.subjectAlternativeName, requestExtensions, extControl);
        if (Arrays.equals(expected, extensionValue) == false) {
            failureMsg.append("extension valus is '").append(hex(extensionValue));
            failureMsg.append("' but expected '").append(expected == null ? "not present" : hex(expected))
                    .append("'");
            failureMsg.append("; ");
        }/*from   ww w.  j  a  va2  s.  c o  m*/
        return;
    }

    ASN1Encodable extInRequest = null;
    if (requestExtensions != null) {
        extInRequest = requestExtensions.getExtensionParsedValue(Extension.subjectAlternativeName);
    }

    if (extInRequest == null) {
        failureMsg.append("extension is present but not expected");
        failureMsg.append("; ");
        return;
    }

    GeneralName[] requested = GeneralNames.getInstance(extInRequest).getNames();

    GeneralName[] is = GeneralNames.getInstance(extensionValue).getNames();

    GeneralName[] expected = new GeneralName[requested.length];
    for (int i = 0; i < is.length; i++) {
        try {
            expected[i] = createGeneralName(is[i], allowedSubjectAltNameModes);
        } catch (BadCertTemplateException e) {
            failureMsg.append("error while processing ").append(i + 1).append("-th name: ")
                    .append(e.getMessage());
            failureMsg.append("; ");
            return;
        }
    }

    if (is.length != expected.length) {
        failureMsg.append("size of GeneralNames is '").append(is.length);
        failureMsg.append("' but expected '").append(expected.length).append("'");
        failureMsg.append("; ");
        return;
    }

    for (int i = 0; i < is.length; i++) {
        if (is[i].equals(expected[i]) == false) {
            failureMsg.append(i + 1).append("-th name does not match the requested one");
            failureMsg.append("; ");
        }
    }
}

From source file:org.xipki.ca.qa.impl.X509CertprofileQAImpl.java

License:Open Source License

private void checkExtensionSubjectInfoAccess(final StringBuilder failureMsg, final byte[] extensionValue,
        final Extensions requestExtensions, final ExtensionControl extControl) {
    if (allowedSubjectInfoAccessModes == null) {
        byte[] expected = getExpectedExtValue(Extension.subjectAlternativeName, requestExtensions, extControl);
        if (Arrays.equals(expected, extensionValue) == false) {
            failureMsg.append("extension valus is '").append(hex(extensionValue));
            failureMsg.append("' but expected '").append(expected == null ? "not present" : hex(expected))
                    .append("'");
            failureMsg.append("; ");
        }//from  w ww  .  ja va 2 s  . c  o m
        return;
    }

    ASN1Encodable requestExtValue = null;
    if (requestExtensions != null) {
        requestExtValue = requestExtensions.getExtensionParsedValue(Extension.subjectInfoAccess);
    }
    if (requestExtValue == null) {
        failureMsg.append("extension is present but not expected");
        failureMsg.append("; ");
        return;
    }

    ASN1Sequence requestSeq = ASN1Sequence.getInstance(requestExtValue);
    ASN1Sequence certSeq = ASN1Sequence.getInstance(extensionValue);

    int n = requestSeq.size();

    if (certSeq.size() != n) {
        failureMsg.append("size of GeneralNames is '").append(certSeq.size());
        failureMsg.append("' but expected '").append(n).append("'");
        failureMsg.append("; ");
        return;
    }

    for (int i = 0; i < n; i++) {
        AccessDescription ad = AccessDescription.getInstance(requestSeq.getObjectAt(i));
        ASN1ObjectIdentifier accessMethod = ad.getAccessMethod();

        Set<GeneralNameMode> generalNameModes;
        if (accessMethod == null) {
            generalNameModes = allowedSubjectInfoAccessModes.get(X509Certprofile.OID_ZERO);
        } else {
            generalNameModes = allowedSubjectInfoAccessModes.get(accessMethod);
        }

        if (generalNameModes == null) {
            failureMsg.append("accessMethod in requestExtension ");
            failureMsg.append(accessMethod == null ? "NULL" : accessMethod.getId());
            failureMsg.append(" is not allowed");
            failureMsg.append("; ");
            continue;
        }

        AccessDescription certAccessDesc = AccessDescription.getInstance(certSeq.getObjectAt(i));
        ASN1ObjectIdentifier certAccessMethod = certAccessDesc.getAccessMethod();

        boolean b;
        if (accessMethod == null) {
            b = certAccessDesc == null;
        } else {
            b = accessMethod.equals(certAccessMethod);
        }

        if (b == false) {
            failureMsg.append("accessMethod is '")
                    .append(certAccessMethod == null ? "null" : certAccessMethod.getId());
            failureMsg.append("' but expected '").append(accessMethod == null ? "null" : accessMethod.getId());
            failureMsg.append("; ");
            continue;
        }

        GeneralName accessLocation;
        try {
            accessLocation = createGeneralName(ad.getAccessLocation(), generalNameModes);
        } catch (BadCertTemplateException e) {
            failureMsg.append("invalid requestExtension: " + e.getMessage());
            failureMsg.append("; ");
            continue;
        }

        GeneralName certAccessLocation = certAccessDesc.getAccessLocation();
        if (certAccessLocation.equals(accessLocation) == false) {
            failureMsg.append("accessLocation does not match the requested one");
            failureMsg.append("; ");
        }
    }
}

From source file:org.xipki.ca.server.impl.IdentifiedX509Certprofile.java

License:Open Source License

private static GeneralNames createRequestedSubjectAltNames(final Extensions requestExtensions,
        final Set<GeneralNameMode> modes) throws BadCertTemplateException {
    ASN1Encodable extValue = requestExtensions.getExtensionParsedValue(Extension.subjectAlternativeName);
    if (extValue == null) {
        return null;
    }/*from w ww. j a v  a2 s.  c  o  m*/

    GeneralNames reqNames = GeneralNames.getInstance(extValue);
    if (modes == null) {
        return reqNames;
    }

    GeneralName[] reqL = reqNames.getNames();
    GeneralName[] l = new GeneralName[reqL.length];
    for (int i = 0; i < reqL.length; i++) {
        l[i] = createGeneralName(reqL[i], modes);
    }
    return new GeneralNames(l);
}

From source file:org.xipki.ca.server.impl.IdentifiedX509Certprofile.java

License:Open Source License

private static ASN1Sequence createSubjectInfoAccess(final Extensions requestExtensions,
        final Map<ASN1ObjectIdentifier, Set<GeneralNameMode>> modes) throws BadCertTemplateException {
    ASN1Encodable extValue = requestExtensions.getExtensionParsedValue(Extension.subjectInfoAccess);
    if (extValue == null) {
        return null;
    }/*from   w ww  .  j  av  a  2s.  c  om*/

    ASN1Sequence reqSeq = ASN1Sequence.getInstance(extValue);
    int size = reqSeq.size();

    if (modes == null) {
        return reqSeq;
    }

    ASN1EncodableVector v = new ASN1EncodableVector();
    for (int i = 0; i < size; i++) {
        AccessDescription ad = AccessDescription.getInstance(reqSeq.getObjectAt(i));
        ASN1ObjectIdentifier accessMethod = ad.getAccessMethod();
        if (accessMethod == null) {
            accessMethod = X509Certprofile.OID_ZERO;
        }
        Set<GeneralNameMode> generalNameModes = modes.get(accessMethod);

        if (generalNameModes == null) {
            throw new BadCertTemplateException(
                    "subjectInfoAccess.accessMethod " + accessMethod.getId() + " is not allowed");
        }

        GeneralName accessLocation = createGeneralName(ad.getAccessLocation(), generalNameModes);
        v.add(new AccessDescription(accessMethod, accessLocation));
    } // end for

    return v.size() > 0 ? new DERSequence(v) : null;
}

From source file:org.xipki.ca.server.impl.X509CACmpResponder.java

License:Open Source License

private PKIBody revokeOrUnrevokeOrRemoveCertificates(final RevReqContent rr, final AuditEvent auditEvent,
        final Permission permission) {
    RevDetails[] revContent = rr.toRevDetailsArray();

    RevRepContentBuilder repContentBuilder = new RevRepContentBuilder();

    final int n = revContent.length;
    // test the reques
    for (int i = 0; i < n; i++) {
        RevDetails revDetails = revContent[i];

        CertTemplate certDetails = revDetails.getCertDetails();
        X500Name issuer = certDetails.getIssuer();
        ASN1Integer serialNumber = certDetails.getSerialNumber();

        try {/*from   w  ww  .  j a  va  2  s .  c om*/
            X500Name caSubject = getCA().getCAInfo().getCertificate().getSubjectAsX500Name();

            if (issuer == null) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "issuer is not present");
            } else if (issuer.equals(caSubject) == false) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "issuer not targets at the CA");
            } else if (serialNumber == null) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "serialNumber is not present");
            } else if (certDetails.getSigningAlg() != null || certDetails.getValidity() != null
                    || certDetails.getSubject() != null || certDetails.getPublicKey() != null
                    || certDetails.getIssuerUID() != null || certDetails.getSubjectUID() != null
                    || certDetails.getExtensions() != null) {
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badCertTemplate,
                        "only version, issuer and serialNumber in RevDetails.certDetails are allowed, "
                                + "but more is specified");
            }
        } catch (IllegalArgumentException e) {
            return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badRequest,
                    "the request is not invalid");
        }
    }

    for (int i = 0; i < n; i++) {
        AuditChildEvent childAuditEvent = null;
        if (auditEvent != null) {
            childAuditEvent = new AuditChildEvent();
            auditEvent.addChildAuditEvent(childAuditEvent);
        }

        RevDetails revDetails = revContent[i];

        CertTemplate certDetails = revDetails.getCertDetails();
        ASN1Integer serialNumber = certDetails.getSerialNumber();
        // serialNumber is not null due to the check in the previous for-block.

        X500Name caSubject = getCA().getCAInfo().getCertificate().getSubjectAsX500Name();
        BigInteger snBigInt = serialNumber.getPositiveValue();
        CertId certId = new CertId(new GeneralName(caSubject), serialNumber);

        if (childAuditEvent != null) {
            AuditEventData eventData = new AuditEventData("serialNumber", snBigInt.toString());
            childAuditEvent.addEventData(eventData);
        }

        PKIStatusInfo status;

        try {
            Object returnedObj = null;
            X509CA ca = getCA();
            if (Permission.UNREVOKE_CERT == permission) {
                // unrevoke
                returnedObj = ca.unrevokeCertificate(snBigInt);
            } else if (Permission.REMOVE_CERT == permission) {
                // remove
                returnedObj = ca.removeCertificate(snBigInt);
            } else {
                // revoke
                Date invalidityDate = null;
                CRLReason reason = null;

                Extensions crlDetails = revDetails.getCrlEntryDetails();
                if (crlDetails != null) {
                    ASN1ObjectIdentifier extId = Extension.reasonCode;
                    ASN1Encodable extValue = crlDetails.getExtensionParsedValue(extId);
                    if (extValue != null) {
                        int reasonCode = ((ASN1Enumerated) extValue).getValue().intValue();
                        reason = CRLReason.forReasonCode(reasonCode);
                    }

                    extId = Extension.invalidityDate;
                    extValue = crlDetails.getExtensionParsedValue(extId);
                    if (extValue != null) {
                        try {
                            invalidityDate = ((ASN1GeneralizedTime) extValue).getDate();
                        } catch (ParseException e) {
                            throw new OperationException(ErrorCode.INVALID_EXTENSION,
                                    "invalid extension " + extId.getId());
                        }
                    }
                } // end if(crlDetails)

                if (reason == null) {
                    reason = CRLReason.UNSPECIFIED;
                }

                if (childAuditEvent != null) {
                    childAuditEvent.addEventData(new AuditEventData("reason", reason.getDescription()));
                    if (invalidityDate != null) {
                        String value;
                        synchronized (dateFormat) {
                            value = dateFormat.format(invalidityDate);
                        }
                        childAuditEvent.addEventData(new AuditEventData("invalidityDate", value));
                    }
                }

                returnedObj = ca.revokeCertificate(snBigInt, reason, invalidityDate);
            } // end if(permission)

            if (returnedObj == null) {
                throw new OperationException(ErrorCode.UNKNOWN_CERT, "cert not exists");
            }

            status = new PKIStatusInfo(PKIStatus.granted);
            if (childAuditEvent != null) {
                childAuditEvent.setStatus(AuditStatus.SUCCESSFUL);
            }
        } catch (OperationException e) {
            ErrorCode code = e.getErrorCode();
            LOG.warn("{} certificate, OperationException: code={}, message={}",
                    new Object[] { permission.name(), code.name(), e.getErrorMessage() });

            String auditMessage;

            int failureInfo;
            switch (code) {
            case BAD_REQUEST:
                failureInfo = PKIFailureInfo.badRequest;
                auditMessage = "BAD_REQUEST";
                break;
            case CERT_REVOKED:
                failureInfo = PKIFailureInfo.certRevoked;
                auditMessage = "CERT_REVOKED";
                break;
            case CERT_UNREVOKED:
                failureInfo = PKIFailureInfo.notAuthorized;
                auditMessage = "CERT_UNREVOKED";
                break;
            case DATABASE_FAILURE:
                failureInfo = PKIFailureInfo.systemFailure;
                auditMessage = "DATABASE_FAILURE";
                break;
            case INVALID_EXTENSION:
                failureInfo = PKIFailureInfo.unacceptedExtension;
                auditMessage = "INVALID_EXTENSION";
                break;
            case INSUFFICIENT_PERMISSION:
                failureInfo = PKIFailureInfo.notAuthorized;
                auditMessage = "INSUFFICIENT_PERMISSION";
                break;
            case NOT_PERMITTED:
                failureInfo = PKIFailureInfo.notAuthorized;
                auditMessage = "NOT_PERMITTED";
                break;
            case SYSTEM_FAILURE:
                failureInfo = PKIFailureInfo.systemFailure;
                auditMessage = "System_Failure";
                break;
            case SYSTEM_UNAVAILABLE:
                failureInfo = PKIFailureInfo.systemUnavail;
                auditMessage = "System_Unavailable";
                break;
            case UNKNOWN_CERT:
                failureInfo = PKIFailureInfo.badCertId;
                auditMessage = "UNKNOWN_CERT";
                break;
            default:
                failureInfo = PKIFailureInfo.systemFailure;
                auditMessage = "InternalErrorCode " + e.getErrorCode();
                break;
            } // end switch(code)

            if (childAuditEvent != null) {
                childAuditEvent.setStatus(AuditStatus.FAILED);
                childAuditEvent.addEventData(new AuditEventData("message", auditMessage));
            }

            String errorMessage;
            switch (code) {
            case DATABASE_FAILURE:
            case SYSTEM_FAILURE:
                errorMessage = code.name();
                break;
            default:
                errorMessage = code.name() + ": " + e.getErrorMessage();
                break;
            } // end switch(code)

            status = generateCmpRejectionStatus(failureInfo, errorMessage);
        } // end try

        repContentBuilder.add(status, certId);
    } // end for

    return new PKIBody(PKIBody.TYPE_REVOCATION_REP, repContentBuilder.build());
}

From source file:org.xipki.ca.server.impl.X509CACmpResponder.java

License:Open Source License

private PKIBody cmpRevokeOrUnrevokeOrRemoveCertificates(final PKIHeaderBuilder respHeader,
        final CmpControl cmpControl, final PKIHeader reqHeader, final PKIBody reqBody,
        final CmpRequestorInfo requestor, final String user, final ASN1OctetString tid,
        final AuditEvent auditEvent) throws InsuffientPermissionException {
    Permission requiredPermission = null;
    boolean allRevdetailsOfSameType = true;

    RevReqContent rr = (RevReqContent) reqBody.getContent();
    RevDetails[] revContent = rr.toRevDetailsArray();

    int n = revContent.length;
    for (int i = 0; i < n; i++) {
        RevDetails revDetails = revContent[i];
        Extensions crlDetails = revDetails.getCrlEntryDetails();
        int reasonCode = CRLReason.UNSPECIFIED.getCode();
        if (crlDetails != null) {
            ASN1ObjectIdentifier extId = Extension.reasonCode;
            ASN1Encodable extValue = crlDetails.getExtensionParsedValue(extId);
            if (extValue != null) {
                reasonCode = ((ASN1Enumerated) extValue).getValue().intValue();
            }/*from  w ww  . j  av a 2s  .  co m*/
        }

        if (reasonCode == XipkiCmpConstants.CRL_REASON_REMOVE) {
            if (requiredPermission == null) {
                addAutitEventType(auditEvent, "CERT_REMOVE");
                requiredPermission = Permission.REMOVE_CERT;
            } else if (requiredPermission != Permission.REMOVE_CERT) {
                allRevdetailsOfSameType = false;
                break;
            }
        } else if (reasonCode == CRLReason.REMOVE_FROM_CRL.getCode()) {
            if (requiredPermission == null) {
                addAutitEventType(auditEvent, "CERT_UNREVOKE");
                requiredPermission = Permission.UNREVOKE_CERT;
            } else if (requiredPermission != Permission.UNREVOKE_CERT) {
                allRevdetailsOfSameType = false;
                break;
            }
        } else {
            if (requiredPermission == null) {
                addAutitEventType(auditEvent, "CERT_REVOKE");
                requiredPermission = Permission.REVOKE_CERT;
            } else if (requiredPermission != Permission.REVOKE_CERT) {
                allRevdetailsOfSameType = false;
                break;
            }
        }
    }

    if (allRevdetailsOfSameType == false) {
        ErrorMsgContent emc = new ErrorMsgContent(new PKIStatusInfo(PKIStatus.rejection,
                new PKIFreeText("not all revDetails are of the same type"),
                new PKIFailureInfo(PKIFailureInfo.badRequest)));

        return new PKIBody(PKIBody.TYPE_ERROR, emc);
    } else {
        checkPermission(requestor, requiredPermission);
        return revokeOrUnrevokeOrRemoveCertificates(rr, auditEvent, requiredPermission);
    }
}

From source file:org.xipki.pki.ca.certprofile.XmlX509Certprofile.java

License:Open Source License

private GeneralNames createRequestedSubjectAltNames(final X500Name requestedSubject,
        final X500Name grantedSubject, final Extensions requestedExtensions) throws BadCertTemplateException {
    ASN1Encodable extValue = (requestedExtensions == null) ? null
            : requestedExtensions.getExtensionParsedValue(Extension.subjectAlternativeName);

    if (extValue == null && subjectToSubjectAltNameModes == null) {
        return null;
    }//  w w  w .  j  a va  2s  .  com

    GeneralNames reqNames = (extValue == null) ? null : GeneralNames.getInstance(extValue);
    if (subjectAltNameModes == null && subjectToSubjectAltNameModes == null) {
        return reqNames;
    }

    List<GeneralName> grantedNames = new LinkedList<>();
    // copy the required attributes of Subject
    if (subjectToSubjectAltNameModes != null) {
        for (ASN1ObjectIdentifier attrType : subjectToSubjectAltNameModes.keySet()) {
            GeneralNameTag tag = subjectToSubjectAltNameModes.get(attrType);

            RDN[] rdns = grantedSubject.getRDNs(attrType);
            if (rdns == null) {
                rdns = requestedSubject.getRDNs(attrType);
            }

            if (rdns == null) {
                continue;
            }

            for (RDN rdn : rdns) {
                String rdnValue = X509Util.rdnValueToString(rdn.getFirst().getValue());
                switch (tag) {
                case rfc822Name:
                case dNSName:
                case uniformResourceIdentifier:
                case iPAddress:
                case directoryName:
                case registeredID:
                    grantedNames.add(new GeneralName(tag.getTag(), rdnValue));
                    break;
                default:
                    throw new RuntimeException("should not reach here, unknown GeneralName tag " + tag);
                } // end switch (tag)
            }
        }
    }

    // copy the requested SubjectAltName entries
    if (reqNames != null) {
        GeneralName[] reqL = reqNames.getNames();
        for (int i = 0; i < reqL.length; i++) {
            grantedNames.add(X509CertprofileUtil.createGeneralName(reqL[i], subjectAltNameModes));
        }
    }

    return grantedNames.isEmpty() ? null : new GeneralNames(grantedNames.toArray(new GeneralName[0]));
}

From source file:org.xipki.pki.ca.qa.ExtensionsChecker.java

License:Open Source License

private void checkExtensionSubjectDirAttrs(final StringBuilder failureMsg, final byte[] extensionValue,
        final Extensions requestedExtensions, final ExtensionControl extControl) {
    SubjectDirectoryAttributesControl conf = certProfile.getSubjectDirAttrsControl();
    if (conf == null) {
        failureMsg.append("extension is present but not expected; ");
        return;//w  ww. j a va  2s  .  c o  m
    }

    ASN1Encodable extInRequest = null;
    if (requestedExtensions != null) {
        extInRequest = requestedExtensions.getExtensionParsedValue(Extension.subjectDirectoryAttributes);
    }

    if (extInRequest == null) {
        failureMsg.append("extension is present but not expected; ");
        return;
    }

    SubjectDirectoryAttributes requested = SubjectDirectoryAttributes.getInstance(extInRequest);
    Vector<?> reqSubDirAttrs = requested.getAttributes();
    ASN1GeneralizedTime expDateOfBirth = null;
    String expPlaceOfBirth = null;
    String expGender = null;
    Set<String> expCountryOfCitizenshipList = new HashSet<>();
    Set<String> expCountryOfResidenceList = new HashSet<>();
    Map<ASN1ObjectIdentifier, Set<ASN1Encodable>> expOtherAttrs = new HashMap<>();

    final int expN = reqSubDirAttrs.size();
    for (int i = 0; i < expN; i++) {
        Attribute attr = Attribute.getInstance(reqSubDirAttrs.get(i));
        ASN1ObjectIdentifier attrType = attr.getAttrType();
        ASN1Encodable attrVal = attr.getAttributeValues()[0];

        if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) {
            expDateOfBirth = ASN1GeneralizedTime.getInstance(attrVal);
        } else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) {
            expPlaceOfBirth = DirectoryString.getInstance(attrVal).getString();
        } else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) {
            expGender = DERPrintableString.getInstance(attrVal).getString();
        } else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) {
            String country = DERPrintableString.getInstance(attrVal).getString();
            expCountryOfCitizenshipList.add(country);
        } else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) {
            String country = DERPrintableString.getInstance(attrVal).getString();
            expCountryOfResidenceList.add(country);
        } else {
            Set<ASN1Encodable> otherAttrVals = expOtherAttrs.get(attrType);
            if (otherAttrVals == null) {
                otherAttrVals = new HashSet<>();
                expOtherAttrs.put(attrType, otherAttrVals);
            }
            otherAttrVals.add(attrVal);
        }
    }

    SubjectDirectoryAttributes ext = SubjectDirectoryAttributes.getInstance(extensionValue);
    Vector<?> subDirAttrs = ext.getAttributes();
    ASN1GeneralizedTime dateOfBirth = null;
    String placeOfBirth = null;
    String gender = null;
    Set<String> countryOfCitizenshipList = new HashSet<>();
    Set<String> countryOfResidenceList = new HashSet<>();
    Map<ASN1ObjectIdentifier, Set<ASN1Encodable>> otherAttrs = new HashMap<>();

    List<ASN1ObjectIdentifier> attrTypes = new LinkedList<>(conf.getTypes());
    final int n = subDirAttrs.size();
    for (int i = 0; i < n; i++) {
        Attribute attr = Attribute.getInstance(subDirAttrs.get(i));
        ASN1ObjectIdentifier attrType = attr.getAttrType();
        if (!attrTypes.contains(attrType)) {
            failureMsg.append("attribute of type " + attrType.getId() + " is present but not expected; ");
            continue;
        }

        ASN1Encodable[] attrs = attr.getAttributeValues();
        if (attrs.length != 1) {
            failureMsg.append("attribute of type " + attrType.getId() + " does not single-value value: "
                    + attrs.length + "; ");
            continue;
        }

        ASN1Encodable attrVal = attrs[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 {
            Set<ASN1Encodable> otherAttrVals = otherAttrs.get(attrType);
            if (otherAttrVals == null) {
                otherAttrVals = new HashSet<>();
                otherAttrs.put(attrType, otherAttrVals);
            }
            otherAttrVals.add(attrVal);
        }
    }

    if (dateOfBirth != null) {
        attrTypes.remove(ObjectIdentifiers.DN_DATE_OF_BIRTH);
    }

    if (placeOfBirth != null) {
        attrTypes.remove(ObjectIdentifiers.DN_PLACE_OF_BIRTH);
    }

    if (gender != null) {
        attrTypes.remove(ObjectIdentifiers.DN_GENDER);
    }

    if (!countryOfCitizenshipList.isEmpty()) {
        attrTypes.remove(ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP);
    }

    if (!countryOfResidenceList.isEmpty()) {
        attrTypes.remove(ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE);
    }

    attrTypes.removeAll(otherAttrs.keySet());

    if (!attrTypes.isEmpty()) {
        List<String> attrTypeTexts = new LinkedList<>();
        for (ASN1ObjectIdentifier oid : attrTypes) {
            attrTypeTexts.add(oid.getId());
        }
        failureMsg.append("required attributes of types " + attrTypeTexts + " are not present; ");
    }

    if (dateOfBirth != null) {
        String timeStirng = dateOfBirth.getTimeString();
        if (!SubjectDnSpec.PATTERN_DATE_OF_BIRTH.matcher(timeStirng).matches()) {
            failureMsg.append("invalid dateOfBirth: " + timeStirng + "; ");
        }

        String exp = (expDateOfBirth == null) ? null : expDateOfBirth.getTimeString();
        if (!timeStirng.equalsIgnoreCase(exp)) {
            addViolation(failureMsg, "dateOfBirth", timeStirng, exp);
        }
    }

    if (gender != null) {
        if (!(gender.equalsIgnoreCase("F") || gender.equalsIgnoreCase("M"))) {
            failureMsg.append("invalid gender: " + gender + "; ");
        }
        if (!gender.equalsIgnoreCase(expGender)) {
            addViolation(failureMsg, "gender", gender, expGender);
        }
    }

    if (placeOfBirth != null) {
        if (!placeOfBirth.equals(expPlaceOfBirth)) {
            addViolation(failureMsg, "placeOfBirth", placeOfBirth, expPlaceOfBirth);
        }
    }

    if (!countryOfCitizenshipList.isEmpty()) {
        Set<String> diffs = strInBnotInA(expCountryOfCitizenshipList, countryOfCitizenshipList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfCitizenship ").append(diffs.toString());
            failureMsg.append(" are present but not expected; ");
        }

        diffs = strInBnotInA(countryOfCitizenshipList, expCountryOfCitizenshipList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfCitizenship ").append(diffs.toString());
            failureMsg.append(" are absent but are required; ");
        }
    }

    if (!countryOfResidenceList.isEmpty()) {
        Set<String> diffs = strInBnotInA(expCountryOfResidenceList, countryOfResidenceList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfResidence ").append(diffs.toString());
            failureMsg.append(" are present but not expected; ");
        }

        diffs = strInBnotInA(countryOfResidenceList, expCountryOfResidenceList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfResidence ").append(diffs.toString());
            failureMsg.append(" are absent but are required; ");
        }
    }

    if (!otherAttrs.isEmpty()) {
        for (ASN1ObjectIdentifier attrType : otherAttrs.keySet()) {
            Set<ASN1Encodable> expAttrValues = expOtherAttrs.get(attrType);
            if (expAttrValues == null) {
                failureMsg.append("attribute of type " + attrType.getId() + " is present but not requested; ");
                continue;
            }
            Set<ASN1Encodable> attrValues = otherAttrs.get(attrType);
            if (!attrValues.equals(expAttrValues)) {
                failureMsg
                        .append("attribute of type " + attrType.getId() + " differs from the requested one; ");
                continue;
            }
        }
    }
}

From source file:org.xipki.pki.ca.qa.ExtensionsChecker.java

License:Open Source License

private GeneralName[] getRequestedSubjectAltNames(final X500Name requestedSubject,
        final Extensions requestedExtensions) throws CertprofileException, BadCertTemplateException {
    ASN1Encodable extValue = (requestedExtensions == null) ? null
            : requestedExtensions.getExtensionParsedValue(Extension.subjectAlternativeName);

    Map<ASN1ObjectIdentifier, GeneralNameTag> subjectToSubjectAltNameModes = certProfile
            .getSubjectToSubjectAltNameModes();
    if (extValue == null && subjectToSubjectAltNameModes == null) {
        return null;
    }/*from   www .  j av  a  2  s .c o  m*/

    GeneralNames reqNames = (extValue == null) ? null : GeneralNames.getInstance(extValue);

    Set<GeneralNameMode> subjectAltNameModes = certProfile.getSubjectAltNameModes();
    if (subjectAltNameModes == null && subjectToSubjectAltNameModes == null) {
        return (reqNames == null) ? null : reqNames.getNames();
    }

    List<GeneralName> grantedNames = new LinkedList<>();
    // copy the required attributes of Subject
    if (subjectToSubjectAltNameModes != null) {
        X500Name grantedSubject;
        try {
            grantedSubject = certProfile.getSubject(requestedSubject).getGrantedSubject();
        } catch (CertprofileException | BadCertTemplateException ex) {
            if (certProfile.getSpecialCertprofileBehavior() == null) {
                throw ex;
            }

            LogUtil.warn(LOG, ex, "could not derive granted subject from requested subject");
            grantedSubject = requestedSubject;
        }

        for (ASN1ObjectIdentifier attrType : subjectToSubjectAltNameModes.keySet()) {
            GeneralNameTag tag = subjectToSubjectAltNameModes.get(attrType);

            RDN[] rdns = grantedSubject.getRDNs(attrType);
            if (rdns == null) {
                rdns = requestedSubject.getRDNs(attrType);
            }

            if (rdns == null) {
                continue;
            }

            for (RDN rdn : rdns) {
                String rdnValue = X509Util.rdnValueToString(rdn.getFirst().getValue());
                switch (tag) {
                case rfc822Name:
                case dNSName:
                case uniformResourceIdentifier:
                case iPAddress:
                case directoryName:
                case registeredID:
                    grantedNames.add(new GeneralName(tag.getTag(), rdnValue));
                    break;
                default:
                    throw new RuntimeException("should not reach here, unknown GeneralName tag " + tag);
                } // end switch (tag)
            }
        }
    }

    // copy the requested SubjectAltName entries
    if (reqNames != null) {
        GeneralName[] reqL = reqNames.getNames();
        for (int i = 0; i < reqL.length; i++) {
            grantedNames.add(reqL[i]);
        }
    }

    return grantedNames.isEmpty() ? null : grantedNames.toArray(new GeneralName[0]);
}