Search in sources :

Example 11 with AuthorityInformationAccess

use of com.github.zhenwei.core.asn1.x509.AuthorityInformationAccess in project pri-fidoiot by secure-device-onboard.

the class OnDieCertSignatureFunction method getIssuingCertificate.

private String getIssuingCertificate(Certificate cert) throws IllegalArgumentException, IOException, CertificateEncodingException {
    X509CertificateHolder certholder = new X509CertificateHolder(cert.getEncoded());
    AuthorityInformationAccess aia = AuthorityInformationAccess.fromExtensions(certholder.getExtensions());
    if (aia == null) {
        throw new IllegalArgumentException("AuthorityInformationAccess Extension missing from device certificate.");
    }
    AccessDescription[] descs = aia.getAccessDescriptions();
    if (descs.length != 1) {
        throw new IllegalArgumentException("Too many descriptions in AIA certificate extension: " + descs.length);
    }
    return descs[0].getAccessLocation().getName().toString();
}
Also used : AuthorityInformationAccess(org.bouncycastle.asn1.x509.AuthorityInformationAccess) AccessDescription(org.bouncycastle.asn1.x509.AccessDescription) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder)

Example 12 with AuthorityInformationAccess

use of com.github.zhenwei.core.asn1.x509.AuthorityInformationAccess in project LinLong-Java by zhenwei1108.

the class PKIXCertPathReviewer method checkSignatures.

/*
   * checks: - signatures - name chaining - validity of certificates - todo:
   * if certificate revoked (if specified in the parameters)
   */
private void checkSignatures() {
    // 1.6.1 - Inputs
    // d)
    TrustAnchor trust = null;
    X500Principal trustPrincipal = null;
    // validation date
    {
        ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.certPathValidDate", new Object[] { new TrustedInput(validDate), new TrustedInput(currentDate) });
        addNotification(msg);
    }
    // find trust anchors
    try {
        X509Certificate cert = (X509Certificate) certs.get(certs.size() - 1);
        Collection trustColl = getTrustAnchors(cert, pkixParams.getTrustAnchors());
        if (trustColl.size() > 1) {
            // conflicting trust anchors
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.conflictingTrustAnchors", new Object[] { Integers.valueOf(trustColl.size()), new UntrustedInput(cert.getIssuerX500Principal()) });
            addError(msg);
        } else if (trustColl.isEmpty()) {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.noTrustAnchorFound", new Object[] { new UntrustedInput(cert.getIssuerX500Principal()), Integers.valueOf(pkixParams.getTrustAnchors().size()) });
            addError(msg);
        } else {
            PublicKey trustPublicKey;
            trust = (TrustAnchor) trustColl.iterator().next();
            if (trust.getTrustedCert() != null) {
                trustPublicKey = trust.getTrustedCert().getPublicKey();
            } else {
                trustPublicKey = trust.getCAPublicKey();
            }
            try {
                CertPathValidatorUtilities.verifyX509Certificate(cert, trustPublicKey, pkixParams.getSigProvider());
            } catch (SignatureException e) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.trustButInvalidCert");
                addError(msg);
            } catch (Exception e) {
            // do nothing, error occurs again later
            }
        }
    } catch (CertPathReviewerException cpre) {
        addError(cpre.getErrorMessage());
    } catch (Throwable t) {
        ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.unknown", new Object[] { new UntrustedInput(t.getMessage()), new UntrustedInput(t) });
        addError(msg);
    }
    if (trust != null) {
        // get the name of the trustAnchor
        X509Certificate sign = trust.getTrustedCert();
        try {
            if (sign != null) {
                trustPrincipal = getSubjectPrincipal(sign);
            } else {
                trustPrincipal = new X500Principal(trust.getCAName());
            }
        } catch (IllegalArgumentException ex) {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.trustDNInvalid", new Object[] { new UntrustedInput(trust.getCAName()) });
            addError(msg);
        }
        // test key usages of the trust anchor
        if (sign != null) {
            boolean[] ku = sign.getKeyUsage();
            if (ku != null && (ku.length <= 5 || !ku[5])) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.trustKeyUsage");
                addNotification(msg);
            }
        }
    }
    // 1.6.2 - Initialization
    PublicKey workingPublicKey = null;
    X500Principal workingIssuerName = trustPrincipal;
    X509Certificate sign = null;
    AlgorithmIdentifier workingAlgId = null;
    ASN1ObjectIdentifier workingPublicKeyAlgorithm = null;
    ASN1Encodable workingPublicKeyParameters = null;
    if (trust != null) {
        sign = trust.getTrustedCert();
        if (sign != null) {
            workingPublicKey = sign.getPublicKey();
        } else {
            workingPublicKey = trust.getCAPublicKey();
        }
        try {
            workingAlgId = getAlgorithmIdentifier(workingPublicKey);
            workingPublicKeyAlgorithm = workingAlgId.getAlgorithm();
            workingPublicKeyParameters = workingAlgId.getParameters();
        } catch (CertPathValidatorException ex) {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.trustPubKeyError");
            addError(msg);
            workingAlgId = null;
        }
    }
    // Basic cert checks
    X509Certificate cert = null;
    int i;
    for (int index = certs.size() - 1; index >= 0; index--) {
        // 
        // i as defined in the algorithm description
        // 
        i = n - index;
        // 
        // set certificate to be checked in this round
        // sign and workingPublicKey and workingIssuerName are set
        // at the end of the for loop and initialied the
        // first time from the TrustAnchor
        // 
        cert = (X509Certificate) certs.get(index);
        // verify signature
        if (workingPublicKey != null) {
            try {
                CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey, pkixParams.getSigProvider());
            } catch (GeneralSecurityException ex) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.signatureNotVerified", new Object[] { ex.getMessage(), ex, ex.getClass().getName() });
                addError(msg, index);
            }
        } else if (isSelfIssued(cert)) {
            try {
                CertPathValidatorUtilities.verifyX509Certificate(cert, cert.getPublicKey(), pkixParams.getSigProvider());
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.rootKeyIsValidButNotATrustAnchor");
                addError(msg, index);
            } catch (GeneralSecurityException ex) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.signatureNotVerified", new Object[] { ex.getMessage(), ex, ex.getClass().getName() });
                addError(msg, index);
            }
        } else {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.NoIssuerPublicKey");
            // if there is an authority key extension add the serial and issuer of the missing certificate
            byte[] akiBytes = cert.getExtensionValue(Extension.authorityKeyIdentifier.getId());
            if (akiBytes != null) {
                AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(DEROctetString.getInstance(akiBytes).getOctets());
                GeneralNames issuerNames = aki.getAuthorityCertIssuer();
                if (issuerNames != null) {
                    GeneralName name = issuerNames.getNames()[0];
                    BigInteger serial = aki.getAuthorityCertSerialNumber();
                    if (serial != null) {
                        Object[] extraArgs = { new LocaleString(RESOURCE_NAME, "missingIssuer"), " \"", name, "\" ", new LocaleString(RESOURCE_NAME, "missingSerial"), " ", serial };
                        msg.setExtraArguments(extraArgs);
                    }
                }
            }
            addError(msg, index);
        }
        // certificate valid?
        try {
            cert.checkValidity(validDate);
        } catch (CertificateNotYetValidException cnve) {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.certificateNotYetValid", new Object[] { new TrustedInput(cert.getNotBefore()) });
            addError(msg, index);
        } catch (CertificateExpiredException cee) {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.certificateExpired", new Object[] { new TrustedInput(cert.getNotAfter()) });
            addError(msg, index);
        }
        // certificate revoked?
        if (pkixParams.isRevocationEnabled()) {
            // read crl distribution points extension
            CRLDistPoint crlDistPoints = null;
            try {
                ASN1Primitive crl_dp = getExtensionValue(cert, CRL_DIST_POINTS);
                if (crl_dp != null) {
                    crlDistPoints = CRLDistPoint.getInstance(crl_dp);
                }
            } catch (AnnotatedException ae) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.crlDistPtExtError");
                addError(msg, index);
            }
            // read authority information access extension
            AuthorityInformationAccess authInfoAcc = null;
            try {
                ASN1Primitive auth_info_acc = getExtensionValue(cert, AUTH_INFO_ACCESS);
                if (auth_info_acc != null) {
                    authInfoAcc = AuthorityInformationAccess.getInstance(auth_info_acc);
                }
            } catch (AnnotatedException ae) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.crlAuthInfoAccError");
                addError(msg, index);
            }
            Vector crlDistPointUrls = getCRLDistUrls(crlDistPoints);
            Vector ocspUrls = getOCSPUrls(authInfoAcc);
            // add notifications with the crl distribution points
            // output crl distribution points
            Iterator urlIt = crlDistPointUrls.iterator();
            while (urlIt.hasNext()) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.crlDistPoint", new Object[] { new UntrustedUrlInput(urlIt.next()) });
                addNotification(msg, index);
            }
            // output ocsp urls
            urlIt = ocspUrls.iterator();
            while (urlIt.hasNext()) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.ocspLocation", new Object[] { new UntrustedUrlInput(urlIt.next()) });
                addNotification(msg, index);
            }
            // check CRLs
            try {
                checkRevocation(pkixParams, cert, validDate, sign, workingPublicKey, crlDistPointUrls, ocspUrls, index);
            } catch (CertPathReviewerException cpre) {
                addError(cpre.getErrorMessage(), index);
            }
        }
        // certificate issuer correct
        if (workingIssuerName != null && !cert.getIssuerX500Principal().equals(workingIssuerName)) {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.certWrongIssuer", new Object[] { workingIssuerName.getName(), cert.getIssuerX500Principal().getName() });
            addError(msg, index);
        }
        // 
        if (i != n) {
            if (cert != null && cert.getVersion() == 1) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.noCACert");
                addError(msg, index);
            }
            // k)
            BasicConstraints bc;
            try {
                bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS));
                if (bc != null) {
                    if (!bc.isCA()) {
                        ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.noCACert");
                        addError(msg, index);
                    }
                } else {
                    ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.noBasicConstraints");
                    addError(msg, index);
                }
            } catch (AnnotatedException ae) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.errorProcesingBC");
                addError(msg, index);
            }
            // n)
            boolean[] keyUsage = cert.getKeyUsage();
            if (keyUsage != null && (keyUsage.length <= KEY_CERT_SIGN || !keyUsage[KEY_CERT_SIGN])) {
                ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.noCertSign");
                addError(msg, index);
            }
        }
        // if
        // set signing certificate for next round
        sign = cert;
        // c)
        workingIssuerName = cert.getSubjectX500Principal();
        try {
            workingPublicKey = getNextWorkingKey(certs, index);
            workingAlgId = getAlgorithmIdentifier(workingPublicKey);
            workingPublicKeyAlgorithm = workingAlgId.getAlgorithm();
            workingPublicKeyParameters = workingAlgId.getParameters();
        } catch (CertPathValidatorException ex) {
            ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, "CertPathReviewer.pubKeyError");
            addError(msg, index);
            workingAlgId = null;
            workingPublicKeyAlgorithm = null;
            workingPublicKeyParameters = null;
        }
    }
    // for
    trustAnchor = trust;
    subjectPublicKey = workingPublicKey;
}
Also used : AuthorityInformationAccess(com.github.zhenwei.core.asn1.x509.AuthorityInformationAccess) CertificateNotYetValidException(java.security.cert.CertificateNotYetValidException) CertificateExpiredException(java.security.cert.CertificateExpiredException) AuthorityKeyIdentifier(com.github.zhenwei.core.asn1.x509.AuthorityKeyIdentifier) SignatureException(java.security.SignatureException) UntrustedUrlInput(com.github.zhenwei.core.i18n.filter.UntrustedUrlInput) AlgorithmIdentifier(com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier) TrustedInput(com.github.zhenwei.core.i18n.filter.TrustedInput) Iterator(java.util.Iterator) ASN1Encodable(com.github.zhenwei.core.asn1.ASN1Encodable) UntrustedInput(com.github.zhenwei.core.i18n.filter.UntrustedInput) CRLDistPoint(com.github.zhenwei.core.asn1.x509.CRLDistPoint) Vector(java.util.Vector) AnnotatedException(com.github.zhenwei.provider.jce.provider.AnnotatedException) LocaleString(com.github.zhenwei.core.i18n.LocaleString) PublicKey(java.security.PublicKey) GeneralSecurityException(java.security.GeneralSecurityException) TrustAnchor(java.security.cert.TrustAnchor) X509Certificate(java.security.cert.X509Certificate) CertificateExpiredException(java.security.cert.CertificateExpiredException) GeneralSecurityException(java.security.GeneralSecurityException) CertPathValidatorException(java.security.cert.CertPathValidatorException) AnnotatedException(com.github.zhenwei.provider.jce.provider.AnnotatedException) SignatureException(java.security.SignatureException) CertificateNotYetValidException(java.security.cert.CertificateNotYetValidException) PKIXNameConstraintValidatorException(com.github.zhenwei.provider.jce.provider.PKIXNameConstraintValidatorException) IOException(java.io.IOException) IssuingDistributionPoint(com.github.zhenwei.core.asn1.x509.IssuingDistributionPoint) CRLDistPoint(com.github.zhenwei.core.asn1.x509.CRLDistPoint) DistributionPoint(com.github.zhenwei.core.asn1.x509.DistributionPoint) CertPathValidatorException(java.security.cert.CertPathValidatorException) ErrorBundle(com.github.zhenwei.core.i18n.ErrorBundle) GeneralNames(com.github.zhenwei.core.asn1.x509.GeneralNames) X500Principal(javax.security.auth.x500.X500Principal) Collection(java.util.Collection) BigInteger(java.math.BigInteger) ASN1TaggedObject(com.github.zhenwei.core.asn1.ASN1TaggedObject) GeneralName(com.github.zhenwei.core.asn1.x509.GeneralName) ASN1Primitive(com.github.zhenwei.core.asn1.ASN1Primitive) BasicConstraints(com.github.zhenwei.core.asn1.x509.BasicConstraints) ASN1ObjectIdentifier(com.github.zhenwei.core.asn1.ASN1ObjectIdentifier)

Example 13 with AuthorityInformationAccess

use of com.github.zhenwei.core.asn1.x509.AuthorityInformationAccess in project LinLong-Java by zhenwei1108.

the class PKIXCertPathReviewer method getOCSPUrls.

protected Vector getOCSPUrls(AuthorityInformationAccess authInfoAccess) {
    Vector urls = new Vector();
    if (authInfoAccess != null) {
        AccessDescription[] ads = authInfoAccess.getAccessDescriptions();
        for (int i = 0; i < ads.length; i++) {
            if (ads[i].getAccessMethod().equals(AccessDescription.id_ad_ocsp)) {
                GeneralName name = ads[i].getAccessLocation();
                if (name.getTagNo() == GeneralName.uniformResourceIdentifier) {
                    String url = ((ASN1IA5String) name.getName()).getString();
                    urls.add(url);
                }
            }
        }
    }
    return urls;
}
Also used : AccessDescription(com.github.zhenwei.core.asn1.x509.AccessDescription) ASN1IA5String(com.github.zhenwei.core.asn1.ASN1IA5String) GeneralName(com.github.zhenwei.core.asn1.x509.GeneralName) ASN1OctetString(com.github.zhenwei.core.asn1.ASN1OctetString) DEROctetString(com.github.zhenwei.core.asn1.DEROctetString) LocaleString(com.github.zhenwei.core.i18n.LocaleString) ASN1IA5String(com.github.zhenwei.core.asn1.ASN1IA5String) Vector(java.util.Vector) IssuingDistributionPoint(com.github.zhenwei.core.asn1.x509.IssuingDistributionPoint) CRLDistPoint(com.github.zhenwei.core.asn1.x509.CRLDistPoint) DistributionPoint(com.github.zhenwei.core.asn1.x509.DistributionPoint)

Example 14 with AuthorityInformationAccess

use of com.github.zhenwei.core.asn1.x509.AuthorityInformationAccess in project module-ballerina-http by ballerina-platform.

the class OCSPVerifier method getAIALocations.

/**
 * Authority Information Access (AIA) is a non-critical extension in an X509 Certificate. This contains the
 * URL of the OCSP endpoint if one is available.
 *
 * @param cert is the certificate
 * @return a lit of URLs in AIA extension of the certificate which will hopefully contain an OCSP endpoint.
 * @throws CertificateVerificationException if any error occurs while retrieving authority access points from the
 * certificate.
 */
public static List<String> getAIALocations(X509Certificate cert) throws CertificateVerificationException {
    // Gets the DER-encoded OCTET string for the extension value for Authority information access points.
    byte[] aiaExtensionValue = cert.getExtensionValue(Extension.authorityInfoAccess.getId());
    if (aiaExtensionValue == null) {
        throw new CertificateVerificationException("Certificate doesn't have Authority Information Access points");
    }
    AuthorityInformationAccess authorityInformationAccess;
    ASN1InputStream asn1InputStream = null;
    try {
        DEROctetString oct = (DEROctetString) (new ASN1InputStream(new ByteArrayInputStream(aiaExtensionValue)).readObject());
        asn1InputStream = new ASN1InputStream(oct.getOctets());
        authorityInformationAccess = AuthorityInformationAccess.getInstance(asn1InputStream.readObject());
    } catch (IOException e) {
        throw new CertificateVerificationException("Cannot read certificate to get OSCP urls", e);
    } finally {
        try {
            if (asn1InputStream != null) {
                asn1InputStream.close();
            }
        } catch (IOException e) {
            LOG.error("Cannot close ASN1InputStream", e);
        }
    }
    List<String> ocspUrlList = new ArrayList<>();
    AccessDescription[] accessDescriptions = authorityInformationAccess.getAccessDescriptions();
    for (AccessDescription accessDescription : accessDescriptions) {
        GeneralName gn = accessDescription.getAccessLocation();
        if (gn.getTagNo() == GeneralName.uniformResourceIdentifier) {
            DERIA5String str = DERIA5String.getInstance(gn.getName());
            String accessLocation = str.getString();
            ocspUrlList.add(accessLocation);
        }
    }
    if (ocspUrlList.isEmpty()) {
        throw new CertificateVerificationException("Cannot get OCSP urls from certificate");
    }
    return ocspUrlList;
}
Also used : AuthorityInformationAccess(org.bouncycastle.asn1.x509.AuthorityInformationAccess) ASN1InputStream(org.bouncycastle.asn1.ASN1InputStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) CertificateVerificationException(io.ballerina.stdlib.http.transport.contractimpl.common.certificatevalidation.CertificateVerificationException) ByteArrayInputStream(java.io.ByteArrayInputStream) AccessDescription(org.bouncycastle.asn1.x509.AccessDescription) GeneralName(org.bouncycastle.asn1.x509.GeneralName)

Example 15 with AuthorityInformationAccess

use of com.github.zhenwei.core.asn1.x509.AuthorityInformationAccess in project oxAuth by GluuFederation.

the class OCSPCertificateVerifier method getOCSPUrl.

@SuppressWarnings({ "deprecation", "resource" })
private String getOCSPUrl(X509Certificate certificate) throws IOException {
    ASN1Primitive obj;
    try {
        obj = getExtensionValue(certificate, Extension.authorityInfoAccess.getId());
    } catch (IOException ex) {
        log.error("Failed to get OCSP URL", ex);
        return null;
    }
    if (obj == null) {
        return null;
    }
    AuthorityInformationAccess authorityInformationAccess = AuthorityInformationAccess.getInstance(obj);
    AccessDescription[] accessDescriptions = authorityInformationAccess.getAccessDescriptions();
    for (AccessDescription accessDescription : accessDescriptions) {
        boolean correctAccessMethod = accessDescription.getAccessMethod().equals(X509ObjectIdentifiers.ocspAccessMethod);
        if (!correctAccessMethod) {
            continue;
        }
        GeneralName name = accessDescription.getAccessLocation();
        if (name.getTagNo() != GeneralName.uniformResourceIdentifier) {
            continue;
        }
        DERIA5String derStr = DERIA5String.getInstance((ASN1TaggedObject) name.toASN1Primitive(), false);
        return derStr.getString();
    }
    return null;
}
Also used : AuthorityInformationAccess(org.bouncycastle.asn1.x509.AuthorityInformationAccess) DERIA5String(org.bouncycastle.asn1.DERIA5String) AccessDescription(org.bouncycastle.asn1.x509.AccessDescription) IOException(java.io.IOException) GeneralName(org.bouncycastle.asn1.x509.GeneralName) ASN1Primitive(org.bouncycastle.asn1.ASN1Primitive)

Aggregations

AuthorityInformationAccess (org.bouncycastle.asn1.x509.AuthorityInformationAccess)22 AccessDescription (org.bouncycastle.asn1.x509.AccessDescription)19 GeneralName (org.bouncycastle.asn1.x509.GeneralName)14 DERIA5String (org.bouncycastle.asn1.DERIA5String)9 IOException (java.io.IOException)8 ArrayList (java.util.ArrayList)8 DEROctetString (org.bouncycastle.asn1.DEROctetString)7 ASN1Primitive (org.bouncycastle.asn1.ASN1Primitive)5 X500Name (org.bouncycastle.asn1.x500.X500Name)5 BigInteger (java.math.BigInteger)4 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)4 CRLDistPoint (org.bouncycastle.asn1.x509.CRLDistPoint)4 GeneralName (com.github.zhenwei.core.asn1.x509.GeneralName)3 ASN1String (org.bouncycastle.asn1.ASN1String)3 DERSequence (org.bouncycastle.asn1.DERSequence)3 BasicConstraints (org.bouncycastle.asn1.x509.BasicConstraints)3 DistributionPoint (org.bouncycastle.asn1.x509.DistributionPoint)3 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)3 AccessDescription (com.github.zhenwei.core.asn1.x509.AccessDescription)2 AuthorityInformationAccess (com.github.zhenwei.core.asn1.x509.AuthorityInformationAccess)2