Search in sources :

Example 61 with AlgorithmIdentifier

use of org.spongycastle.asn1.x509.AlgorithmIdentifier in project BiglyBT by BiglySoftware.

the class PKCS7SignedData method getEncoded.

/**
 * return the bytes for the PKCS7SignedData object.
 */
public byte[] getEncoded() {
    try {
        digest = sig.sign();
        // Create the set of Hash algorithms. I've assumed this is the
        // set of all hash agorithms used to created the digest in the
        // "signerInfo" structure. I may be wrong.
        // 
        ASN1EncodableVector v = new ASN1EncodableVector();
        for (Iterator i = digestalgos.iterator(); i.hasNext(); ) {
            AlgorithmIdentifier a = new AlgorithmIdentifier(new DERObjectIdentifier((String) i.next()), null);
            v.add(a);
        }
        DERSet algos = new DERSet(v);
        // Create the contentInfo. Empty, I didn't implement this bit
        // 
        DERSequence contentinfo = new DERSequence(new DERObjectIdentifier(ID_PKCS7_DATA));
        // Get all the certificates
        // 
        v = new ASN1EncodableVector();
        for (Iterator i = certs.iterator(); i.hasNext(); ) {
            DERInputStream tempstream = new DERInputStream(new ByteArrayInputStream(((X509Certificate) i.next()).getEncoded()));
            v.add(tempstream.readObject());
        }
        DERSet dercertificates = new DERSet(v);
        // Create signerinfo structure.
        // 
        ASN1EncodableVector signerinfo = new ASN1EncodableVector();
        // Add the signerInfo version
        // 
        signerinfo.add(new DERInteger(signerversion));
        IssuerAndSerialNumber isAnds = new IssuerAndSerialNumber(new X509Name((ASN1Sequence) getIssuer(signCert.getTBSCertificate())), new DERInteger(signCert.getSerialNumber()));
        signerinfo.add(isAnds);
        // Add the digestAlgorithm
        // 
        signerinfo.add(new AlgorithmIdentifier(new DERObjectIdentifier(digestAlgorithm), new DERNull()));
        // 
        // Add the digestEncryptionAlgorithm
        // 
        signerinfo.add(new AlgorithmIdentifier(new DERObjectIdentifier(digestEncryptionAlgorithm), new DERNull()));
        // 
        // Add the digest
        // 
        signerinfo.add(new DEROctetString(digest));
        // 
        // Finally build the body out of all the components above
        // 
        ASN1EncodableVector body = new ASN1EncodableVector();
        body.add(new DERInteger(version));
        body.add(algos);
        body.add(contentinfo);
        body.add(new DERTaggedObject(false, 0, dercertificates));
        if (crls.size() > 0) {
            v = new ASN1EncodableVector();
            for (Iterator i = crls.iterator(); i.hasNext(); ) {
                DERInputStream t = new DERInputStream(new ByteArrayInputStream((((X509CRL) i.next()).getEncoded())));
                v.add(t.readObject());
            }
            DERSet dercrls = new DERSet(v);
            body.add(new DERTaggedObject(false, 1, dercrls));
        }
        // Only allow one signerInfo
        // 
        body.add(new DERSet(new DERSequence(signerinfo)));
        // Now we have the body, wrap it in it's PKCS7Signed shell
        // and return it
        // 
        ASN1EncodableVector whole = new ASN1EncodableVector();
        whole.add(new DERObjectIdentifier(ID_PKCS7_SIGNED_DATA));
        whole.add(new DERTaggedObject(0, new DERSequence(body)));
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        DEROutputStream dout = new DEROutputStream(bOut);
        dout.writeObject(new DERSequence(whole));
        dout.close();
        return bOut.toByteArray();
    } catch (Exception e) {
        throw new RuntimeException(e.toString());
    }
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) AlgorithmIdentifier(org.gudy.bouncycastle.asn1.x509.AlgorithmIdentifier) X509Name(org.gudy.bouncycastle.asn1.x509.X509Name) ByteArrayInputStream(java.io.ByteArrayInputStream)

Example 62 with AlgorithmIdentifier

use of org.spongycastle.asn1.x509.AlgorithmIdentifier in project xipki by xipki.

the class XmlX509Certprofile method getExtensions.

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

Example 63 with AlgorithmIdentifier

use of org.spongycastle.asn1.x509.AlgorithmIdentifier in project xipki by xipki.

the class CmpRequestor method verifyProtection.

private ProtectionVerificationResult verifyProtection(String tid, GeneralPKIMessage pkiMessage) throws CMPException, InvalidKeyException, OperatorCreationException {
    ProtectedPKIMessage protectedMsg = new ProtectedPKIMessage(pkiMessage);
    if (protectedMsg.hasPasswordBasedMacProtection()) {
        LOG.warn("NOT_SIGNAUTRE_BASED: {}", pkiMessage.getHeader().getProtectionAlg().getAlgorithm().getId());
        return new ProtectionVerificationResult(null, ProtectionResult.NOT_SIGNATURE_BASED);
    }
    PKIHeader header = protectedMsg.getHeader();
    if (recipientName != null) {
        boolean authorizedResponder = true;
        if (header.getSender().getTagNo() != GeneralName.directoryName) {
            authorizedResponder = false;
        } else {
            X500Name msgSender = X500Name.getInstance(header.getSender().getName());
            authorizedResponder = recipientName.equals(msgSender);
        }
        if (!authorizedResponder) {
            LOG.warn("tid={}: not authorized responder '{}'", tid, header.getSender());
            return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
        }
    }
    AlgorithmIdentifier protectionAlgo = protectedMsg.getHeader().getProtectionAlg();
    if (!responder.getSigAlgoValidator().isAlgorithmPermitted(protectionAlgo)) {
        String algoName;
        try {
            algoName = AlgorithmUtil.getSignatureAlgoName(protectionAlgo);
        } catch (NoSuchAlgorithmException ex) {
            algoName = protectionAlgo.getAlgorithm().getId();
        }
        LOG.warn("tid={}: response protected by untrusted protection algorithm '{}'", tid, algoName);
        return new ProtectionVerificationResult(null, ProtectionResult.INVALID);
    }
    X509Certificate cert = responder.getCert();
    ContentVerifierProvider verifierProvider = securityFactory.getContentVerifierProvider(cert);
    if (verifierProvider == null) {
        LOG.warn("tid={}: not authorized responder '{}'", tid, header.getSender());
        return new ProtectionVerificationResult(cert, ProtectionResult.SENDER_NOT_AUTHORIZED);
    }
    boolean signatureValid = protectedMsg.verify(verifierProvider);
    ProtectionResult protRes = signatureValid ? ProtectionResult.VALID : ProtectionResult.INVALID;
    return new ProtectionVerificationResult(cert, protRes);
}
Also used : PKIHeader(org.bouncycastle.asn1.cmp.PKIHeader) ProtectionResult(org.xipki.cmp.ProtectionResult) ProtectedPKIMessage(org.bouncycastle.cert.cmp.ProtectedPKIMessage) ProtectionVerificationResult(org.xipki.cmp.ProtectionVerificationResult) X500Name(org.bouncycastle.asn1.x500.X500Name) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DEROctetString(org.bouncycastle.asn1.DEROctetString) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) X509Certificate(java.security.cert.X509Certificate) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider)

Example 64 with AlgorithmIdentifier

use of org.spongycastle.asn1.x509.AlgorithmIdentifier in project xipki by xipki.

the class PrivateKeyCryptor method decrypt.

PrivateKey decrypt(PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) throws P11TokenException {
    ParamUtil.requireNonNull("encryptedPrivateKeyInfo", encryptedPrivateKeyInfo);
    PrivateKeyInfo privateKeyInfo;
    synchronized (decryptorProvider) {
        try {
            privateKeyInfo = encryptedPrivateKeyInfo.decryptPrivateKeyInfo(decryptorProvider);
        } catch (PKCSException ex) {
            throw new P11TokenException(ex.getMessage(), ex);
        }
    }
    AlgorithmIdentifier keyAlg = privateKeyInfo.getPrivateKeyAlgorithm();
    ASN1ObjectIdentifier keyAlgOid = keyAlg.getAlgorithm();
    String algoName;
    if (PKCSObjectIdentifiers.rsaEncryption.equals(keyAlgOid)) {
        algoName = "RSA";
    } else if (X9ObjectIdentifiers.id_dsa.equals(keyAlgOid)) {
        algoName = "DSA";
    } else if (X9ObjectIdentifiers.id_ecPublicKey.equals(keyAlgOid)) {
        algoName = "EC";
    } else {
        throw new P11TokenException("unknown private key algorithm " + keyAlgOid.getId());
    }
    try {
        KeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance(algoName, "BC");
        return keyFactory.generatePrivate(keySpec);
    } catch (IOException | NoSuchAlgorithmException | NoSuchProviderException | InvalidKeySpecException ex) {
        throw new P11TokenException(ex.getClass().getName() + ": " + ex.getMessage(), ex);
    }
}
Also used : P11TokenException(org.xipki.security.exception.P11TokenException) PKCS8EncodedKeySpec(java.security.spec.PKCS8EncodedKeySpec) KeySpec(java.security.spec.KeySpec) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) PKCSException(org.bouncycastle.pkcs.PKCSException) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) PKCS8EncodedKeySpec(java.security.spec.PKCS8EncodedKeySpec) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) NoSuchProviderException(java.security.NoSuchProviderException) PKCS8EncryptedPrivateKeyInfo(org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo) PrivateKeyInfo(org.bouncycastle.asn1.pkcs.PrivateKeyInfo) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) KeyFactory(java.security.KeyFactory)

Example 65 with AlgorithmIdentifier

use of org.spongycastle.asn1.x509.AlgorithmIdentifier in project xipki by xipki.

the class OcspStatusCmd method processResponse.

@Override
protected Object processResponse(OCSPResp response, X509Certificate respIssuer, IssuerHash issuerHash, List<BigInteger> serialNumbers, Map<BigInteger, byte[]> encodedCerts) throws Exception {
    ParamUtil.requireNonNull("response", response);
    ParamUtil.requireNonNull("issuerHash", issuerHash);
    ParamUtil.requireNonNull("serialNumbers", serialNumbers);
    BasicOCSPResp basicResp = OcspUtils.extractBasicOcspResp(response);
    boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null;
    SingleResp[] singleResponses = basicResp.getResponses();
    if (singleResponses == null || singleResponses.length == 0) {
        throw new CmdFailure("received no status from server");
    }
    final int n = singleResponses.length;
    if (n != serialNumbers.size()) {
        throw new CmdFailure("received status with " + n + " single responses from server, but " + serialNumbers.size() + " were requested");
    }
    Date[] thisUpdates = new Date[n];
    for (int i = 0; i < n; i++) {
        thisUpdates[i] = singleResponses[i].getThisUpdate();
    }
    // check the signature if available
    if (null == basicResp.getSignature()) {
        println("response is not signed");
    } else {
        X509CertificateHolder[] responderCerts = basicResp.getCerts();
        if (responderCerts == null || responderCerts.length < 1) {
            throw new CmdFailure("no responder certificate is contained in the response");
        }
        ResponderID respId = basicResp.getResponderId().toASN1Primitive();
        X500Name respIdByName = respId.getName();
        byte[] respIdByKey = respId.getKeyHash();
        X509CertificateHolder respSigner = null;
        for (X509CertificateHolder cert : responderCerts) {
            if (respIdByName != null) {
                if (cert.getSubject().equals(respIdByName)) {
                    respSigner = cert;
                }
            } else {
                byte[] spkiSha1 = HashAlgo.SHA1.hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes());
                if (Arrays.equals(respIdByKey, spkiSha1)) {
                    respSigner = cert;
                }
            }
            if (respSigner != null) {
                break;
            }
        }
        if (respSigner == null) {
            throw new CmdFailure("no responder certificate match the ResponderId");
        }
        boolean validOn = true;
        for (Date thisUpdate : thisUpdates) {
            validOn = respSigner.isValidOn(thisUpdate);
            if (!validOn) {
                throw new CmdFailure("responder certificate is not valid on " + thisUpdate);
            }
        }
        if (validOn) {
            PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
            ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey);
            boolean sigValid = basicResp.isSignatureValid(cvp);
            if (!sigValid) {
                throw new CmdFailure("response is equipped with invalid signature");
            }
            // verify the OCSPResponse signer
            if (respIssuer != null) {
                boolean certValid = true;
                X509Certificate jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure());
                if (X509Util.issues(respIssuer, jceRespSigner)) {
                    try {
                        jceRespSigner.verify(respIssuer.getPublicKey());
                    } catch (SignatureException ex) {
                        certValid = false;
                    }
                }
                if (!certValid) {
                    throw new CmdFailure("response is equipped with valid signature but the" + " OCSP signer is not trusted");
                }
            } else {
                println("response is equipped with valid signature");
            }
        // end if(respIssuer)
        }
        if (verbose.booleanValue()) {
            println("responder is " + X509Util.getRfc4519Name(responderCerts[0].getSubject()));
        }
    }
    for (int i = 0; i < n; i++) {
        if (n > 1) {
            println("---------------------------- " + i + "----------------------------");
        }
        SingleResp singleResp = singleResponses[i];
        CertificateStatus singleCertStatus = singleResp.getCertStatus();
        String status;
        if (singleCertStatus == null) {
            status = "good";
        } else if (singleCertStatus instanceof RevokedStatus) {
            RevokedStatus revStatus = (RevokedStatus) singleCertStatus;
            Date revTime = revStatus.getRevocationTime();
            Date invTime = null;
            Extension ext = singleResp.getExtension(Extension.invalidityDate);
            if (ext != null) {
                invTime = ASN1GeneralizedTime.getInstance(ext.getParsedValue()).getDate();
            }
            if (revStatus.hasRevocationReason()) {
                int reason = revStatus.getRevocationReason();
                if (extendedRevoke && reason == CrlReason.CERTIFICATE_HOLD.getCode() && revTime.getTime() == 0) {
                    status = "unknown (RFC6960)";
                } else {
                    status = StringUtil.concatObjects("revoked, reason = ", CrlReason.forReasonCode(reason).getDescription(), ", revocationTime = ", revTime, (invTime == null ? "" : ", invalidityTime = " + invTime));
                }
            } else {
                status = "revoked, no reason, revocationTime = " + revTime;
            }
        } else if (singleCertStatus instanceof UnknownStatus) {
            status = "unknown (RFC2560)";
        } else {
            status = "ERROR";
        }
        StringBuilder msg = new StringBuilder();
        CertificateID certId = singleResp.getCertID();
        HashAlgo hashAlgo = HashAlgo.getNonNullInstance(certId.getHashAlgOID());
        boolean issuerMatch = issuerHash.match(hashAlgo, certId.getIssuerNameHash(), certId.getIssuerKeyHash());
        BigInteger serialNumber = certId.getSerialNumber();
        msg.append("issuer matched: ").append(issuerMatch);
        msg.append("\nserialNumber: ").append(LogUtil.formatCsn(serialNumber));
        msg.append("\nCertificate status: ").append(status);
        if (verbose.booleanValue()) {
            msg.append("\nthisUpdate: ").append(singleResp.getThisUpdate());
            msg.append("\nnextUpdate: ").append(singleResp.getNextUpdate());
            Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash);
            if (extension != null) {
                msg.append("\nCertHash is provided:\n");
                ASN1Encodable extensionValue = extension.getParsedValue();
                CertHash certHash = CertHash.getInstance(extensionValue);
                ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm();
                byte[] hashValue = certHash.getCertificateHash();
                msg.append("\tHash algo : ").append(hashAlgOid.getId()).append("\n");
                msg.append("\tHash value: ").append(Hex.encode(hashValue)).append("\n");
                if (encodedCerts != null) {
                    byte[] encodedCert = encodedCerts.get(serialNumber);
                    MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId());
                    byte[] expectedHashValue = md.digest(encodedCert);
                    if (Arrays.equals(expectedHashValue, hashValue)) {
                        msg.append("\tThis matches the requested certificate");
                    } else {
                        msg.append("\tThis differs from the requested certificate");
                    }
                }
            }
            // end if (extension != null)
            extension = singleResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff);
            if (extension != null) {
                ASN1Encodable extensionValue = extension.getParsedValue();
                ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(extensionValue);
                msg.append("\nArchive-CutOff: ");
                msg.append(time.getTimeString());
            }
            AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
            if (sigAlg == null) {
                msg.append(("\nresponse is not signed"));
            } else {
                String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
                if (sigAlgName == null) {
                    sigAlgName = "unknown";
                }
                msg.append("\nresponse is signed with ").append(sigAlgName);
            }
            // extensions
            msg.append("\nExtensions: ");
            List<?> extensionOids = basicResp.getExtensionOIDs();
            if (extensionOids == null || extensionOids.size() == 0) {
                msg.append("-");
            } else {
                int size = extensionOids.size();
                for (int j = 0; j < size; j++) {
                    ASN1ObjectIdentifier extensionOid = (ASN1ObjectIdentifier) extensionOids.get(j);
                    String name = EXTENSION_OIDNAME_MAP.get(extensionOid);
                    if (name == null) {
                        msg.append(extensionOid.getId());
                    } else {
                        msg.append(name);
                    }
                    if (j != size - 1) {
                        msg.append(", ");
                    }
                }
            }
        }
        // end if (verbose.booleanValue())
        println(msg.toString());
    }
    // end for
    println("");
    return null;
}
Also used : HashAlgo(org.xipki.security.HashAlgo) ResponderID(org.bouncycastle.asn1.ocsp.ResponderID) ASN1GeneralizedTime(org.bouncycastle.asn1.ASN1GeneralizedTime) X500Name(org.bouncycastle.asn1.x500.X500Name) SignatureException(java.security.SignatureException) UnknownStatus(org.bouncycastle.cert.ocsp.UnknownStatus) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) CmdFailure(org.xipki.console.karaf.CmdFailure) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) MessageDigest(java.security.MessageDigest) SingleResp(org.bouncycastle.cert.ocsp.SingleResp) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider) CertHash(org.bouncycastle.asn1.isismtt.ocsp.CertHash) PublicKey(java.security.PublicKey) CertificateID(org.bouncycastle.cert.ocsp.CertificateID) CertificateStatus(org.bouncycastle.cert.ocsp.CertificateStatus) Date(java.util.Date) X509Certificate(java.security.cert.X509Certificate) Extension(org.bouncycastle.asn1.x509.Extension) RevokedStatus(org.bouncycastle.cert.ocsp.RevokedStatus) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BigInteger(java.math.BigInteger) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Aggregations

AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)114 IOException (java.io.IOException)47 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)36 SubjectPublicKeyInfo (org.bouncycastle.asn1.x509.SubjectPublicKeyInfo)35 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)32 BigInteger (java.math.BigInteger)29 X509Certificate (java.security.cert.X509Certificate)27 X500Name (org.bouncycastle.asn1.x500.X500Name)27 DEROctetString (org.bouncycastle.asn1.DEROctetString)21 ASN1EncodableVector (org.bouncycastle.asn1.ASN1EncodableVector)20 KeyPair (java.security.KeyPair)19 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)19 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)19 Date (java.util.Date)18 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)18 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)17 DERSequence (org.bouncycastle.asn1.DERSequence)16 KeyPairGenerator (java.security.KeyPairGenerator)15 PublicKey (java.security.PublicKey)14 ContentSigner (org.bouncycastle.operator.ContentSigner)14