Search in sources :

Example 51 with ASN1InputStream

use of com.github.zhenwei.core.asn1.ASN1InputStream in project keystore-explorer by kaikramer.

the class OpenSslPvkUtil method load.

/**
 * Load an unencrypted OpenSSL private key from the stream. The encoding of
 * the private key may be PEM or DER.
 *
 * @param pvkData Stream to load the unencrypted private key from
 * @return The private key
 * @throws PrivateKeyEncryptedException If private key is encrypted
 * @throws CryptoException              Problem encountered while loading the private key
 * @throws IOException                  An I/O error occurred
 */
public static PrivateKey load(byte[] pvkData) throws CryptoException, IOException {
    EncryptionType encType = getEncryptionType(pvkData);
    if (encType == null) {
        throw new CryptoException(res.getString("NotValidOpenSsl.exception.message"));
    }
    if (encType == ENCRYPTED) {
        throw new PrivateKeyEncryptedException(res.getString("OpenSslIsEncrypted.exception.message"));
    }
    // Check if stream is PEM encoded
    PemInfo pemInfo = PemUtil.decode(pvkData);
    if (pemInfo != null) {
        // It is - get DER from PEM
        pvkData = pemInfo.getContent();
    }
    try (ASN1InputStream asn1InputStream = new ASN1InputStream(pvkData)) {
        // Read OpenSSL DER structure
        ASN1Primitive openSsl = asn1InputStream.readObject();
        asn1InputStream.close();
        if (openSsl instanceof ASN1Sequence) {
            ASN1Sequence seq = (ASN1Sequence) openSsl;
            if (seq.size() == 9) {
                // RSA private key
                BigInteger version = ((ASN1Integer) seq.getObjectAt(0)).getValue();
                BigInteger modulus = ((ASN1Integer) seq.getObjectAt(1)).getValue();
                BigInteger publicExponent = ((ASN1Integer) seq.getObjectAt(2)).getValue();
                BigInteger privateExponent = ((ASN1Integer) seq.getObjectAt(3)).getValue();
                BigInteger primeP = ((ASN1Integer) seq.getObjectAt(4)).getValue();
                BigInteger primeQ = ((ASN1Integer) seq.getObjectAt(5)).getValue();
                BigInteger primeExponentP = ((ASN1Integer) seq.getObjectAt(6)).getValue();
                BigInteger primeExponenetQ = ((ASN1Integer) seq.getObjectAt(7)).getValue();
                BigInteger crtCoefficient = ((ASN1Integer) seq.getObjectAt(8)).getValue();
                if (!version.equals(VERSION)) {
                    throw new CryptoException(MessageFormat.format(res.getString("OpenSslVersionIncorrect.exception.message"), "" + VERSION.intValue(), "" + version.intValue()));
                }
                RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, primeQ, primeExponentP, primeExponenetQ, crtCoefficient);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                return keyFactory.generatePrivate(rsaPrivateCrtKeySpec);
            } else if (seq.size() == 6) {
                // DSA private key
                BigInteger version = ((ASN1Integer) seq.getObjectAt(0)).getValue();
                BigInteger primeModulusP = ((ASN1Integer) seq.getObjectAt(1)).getValue();
                BigInteger primeQ = ((ASN1Integer) seq.getObjectAt(2)).getValue();
                BigInteger generatorG = ((ASN1Integer) seq.getObjectAt(3)).getValue();
                // publicExponentY not req for pvk: sequence.getObjectAt(4);
                BigInteger secretExponentX = ((ASN1Integer) seq.getObjectAt(5)).getValue();
                if (!version.equals(VERSION)) {
                    throw new CryptoException(MessageFormat.format(res.getString("OpenSslVersionIncorrect.exception.message"), "" + VERSION.intValue(), "" + version.intValue()));
                }
                DSAPrivateKeySpec dsaPrivateKeySpec = new DSAPrivateKeySpec(secretExponentX, primeModulusP, primeQ, generatorG);
                KeyFactory keyFactory = KeyFactory.getInstance("DSA");
                return keyFactory.generatePrivate(dsaPrivateKeySpec);
            } else if (seq.size() >= 2) {
                // EC private key (RFC 5915)
                org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq);
                AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParametersObject());
                PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey);
                return new JcaPEMKeyConverter().getPrivateKey(privInfo);
            } else {
                throw new CryptoException(MessageFormat.format(res.getString("OpenSslSequenceIncorrectSize.exception.message"), "" + seq.size()));
            }
        } else {
            throw new CryptoException(res.getString("OpenSslSequenceNotFound.exception.message"));
        }
    } catch (Exception ex) {
        throw new CryptoException(res.getString("NoLoadOpenSslPrivateKey.exception.message"), ex);
    }
}
Also used : RSAPrivateCrtKeySpec(java.security.spec.RSAPrivateCrtKeySpec) ASN1InputStream(org.bouncycastle.asn1.ASN1InputStream) PemInfo(org.kse.utilities.pem.PemInfo) JcaPEMKeyConverter(org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) CryptoException(org.kse.crypto.CryptoException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) DSAPrivateKeySpec(java.security.spec.DSAPrivateKeySpec) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) BigInteger(java.math.BigInteger) CryptoException(org.kse.crypto.CryptoException) ASN1Primitive(org.bouncycastle.asn1.ASN1Primitive) KeyFactory(java.security.KeyFactory) PrivateKeyInfo(org.bouncycastle.asn1.pkcs.PrivateKeyInfo)

Example 52 with ASN1InputStream

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

the class OcspServerImpl method answer.

// method close
@Override
public OcspRespWithCacheInfo answer(Responder responder2, byte[] request, boolean viaGet) {
    ResponderImpl responder = (ResponderImpl) responder2;
    RequestOption reqOpt = responder.getRequestOption();
    int version;
    try {
        version = OcspRequest.readRequestVersion(request);
    } catch (EncodingException ex) {
        String message = "could not extract version from request";
        LOG.warn(message);
        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
    }
    if (!reqOpt.isVersionAllowed(version)) {
        String message = "invalid request version " + version;
        LOG.warn(message);
        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
    }
    ResponseSigner signer = responder.getSigner();
    OcspServerConf.ResponseOption repOpt = responder.getResponseOption();
    try {
        Object reqOrRrrorResp = checkSignature(request, reqOpt);
        if (reqOrRrrorResp instanceof OcspRespWithCacheInfo) {
            // error
            return (OcspRespWithCacheInfo) reqOrRrrorResp;
        }
        OcspRequest req = (OcspRequest) reqOrRrrorResp;
        List<CertID> requestList = req.getRequestList();
        int requestsSize = requestList.size();
        if (requestsSize > reqOpt.getMaxRequestListCount()) {
            String message = requestsSize + " entries in RequestList, but maximal " + reqOpt.getMaxRequestListCount() + " is allowed";
            LOG.warn(message);
            return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
        }
        // -----begin license -----
        if (!license.isValid()) {
            LOG.error("License not valid, need new license");
            return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
        }
        if (!license.grantAllCAs()) {
            for (CertID cid : requestList) {
                for (OcspStore store : responder.getStores()) {
                    X509Cert caCert = store.getIssuerCert(cid.getIssuer());
                    if (caCert == null) {
                        continue;
                    }
                    String issuerSubject = caCert.getSubjectRfc4519Text();
                    boolean granted = license.grant(issuerSubject);
                    if (!granted) {
                        LOG.error("Not granted for CA {}, need new license", issuerSubject);
                        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
                    }
                }
            }
        }
        license.regulateSpeed();
        // -----end license-----
        OcspRespControl repControl = new OcspRespControl();
        repControl.canCacheInfo = true;
        List<ExtendedExtension> reqExtensions = req.getExtensions();
        List<Extension> respExtensions = new LinkedList<>();
        ExtendedExtension ocspRespExtn = removeExtension(reqExtensions, OID.ID_PKIX_OCSP_RESPONSE);
        if (ocspRespExtn != null) {
            boolean containsBasic = ocspRespExtn.equalsExtnValue(encodedAcceptableResponses_Basic);
            if (!containsBasic) {
                // we need to parse the extension
                byte[] extnValue = new byte[ocspRespExtn.getExtnValueLength()];
                ocspRespExtn.writeExtnValue(extnValue, 0);
                ASN1Sequence seq = ASN1Sequence.getInstance(extnValue);
                final int size = seq.size();
                for (int i = 0; i < size; i++) {
                    ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(i));
                    if (OCSPObjectIdentifiers.id_pkix_ocsp_basic.equals(oid)) {
                        containsBasic = true;
                        break;
                    }
                }
            }
            if (!containsBasic) {
                LOG.warn("basic OCSP response is not accepted by the client");
                return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
            }
        }
        ExtendedExtension nonceExtn = removeExtension(reqExtensions, OID.ID_PKIX_OCSP_NONCE);
        if (nonceExtn != null) {
            if (reqOpt.getNonceOccurrence() == QuadrupleState.forbidden) {
                LOG.warn("nonce forbidden, but is present in the request");
                return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
            }
            if (reqOpt.getNonceOccurrence() == QuadrupleState.ignore) {
                nonceExtn = null;
            } else {
                int len = nonceExtn.getExtnValueLength();
                int min = reqOpt.getNonceMinLen();
                int max = reqOpt.getNonceMaxLen();
                if (len < min || len > max) {
                    LOG.warn("length of nonce {} not within [{},{}]", len, min, max);
                    return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
                }
                repControl.canCacheInfo = false;
                if (nonceExtn.isCritical()) {
                    respExtensions.add(nonceExtn.revertCritical());
                } else {
                    respExtensions.add(nonceExtn);
                }
            }
        } else {
            if (reqOpt.getNonceOccurrence() == QuadrupleState.required) {
                LOG.warn("nonce required, but is not present in the request");
                return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
            }
        }
        ConcurrentContentSigner concurrentSigner = null;
        if (responder.getResponderOption().getMode() != OcspMode.RFC2560) {
            ExtendedExtension extn = removeExtension(reqExtensions, OID.ID_PKIX_OCSP_PREFSIGALGS);
            if (extn != null) {
                ASN1InputStream asn1Stream = new ASN1InputStream(extn.getExtnValueStream());
                List<AlgorithmIdentifier> prefSigAlgs;
                try {
                    ASN1Sequence seq = ASN1Sequence.getInstance(asn1Stream.readObject());
                    final int size = seq.size();
                    prefSigAlgs = new ArrayList<>(size);
                    for (int i = 0; i < size; i++) {
                        prefSigAlgs.add(AlgorithmIdentifier.getInstance(seq.getObjectAt(i)));
                    }
                } finally {
                    asn1Stream.close();
                }
                concurrentSigner = signer.getSignerForPreferredSigAlgs(prefSigAlgs);
            }
        }
        if (!reqExtensions.isEmpty()) {
            boolean flag = false;
            for (ExtendedExtension m : reqExtensions) {
                if (m.isCritical()) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                if (LOG.isWarnEnabled()) {
                    List<OID> oids = new LinkedList<>();
                    for (ExtendedExtension m : reqExtensions) {
                        if (m.isCritical()) {
                            oids.add(m.getExtnType());
                        }
                    }
                    LOG.warn("could not process critical request extensions: {}", oids);
                }
                return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
            }
        }
        if (concurrentSigner == null) {
            concurrentSigner = signer.getFirstSigner();
        }
        SignAlgo cacheDbSigAlg = null;
        BigInteger cacheDbSerialNumber = null;
        IssuerEntry cacheDbIssuer = null;
        boolean canCacheDb = (requestsSize == 1) && (responseCacher != null) && (nonceExtn == null) && responseCacher.isOnService();
        if (canCacheDb) {
            // try to find the cached response
            CertID certId = requestList.get(0);
            HashAlgo reqHashAlgo = certId.getIssuer().hashAlgorithm();
            if (!reqOpt.allows(reqHashAlgo)) {
                LOG.warn("CertID.hashAlgorithm {} not allowed", reqHashAlgo != null ? reqHashAlgo : certId.getIssuer().hashAlgorithmOID());
                return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
            }
            cacheDbSigAlg = concurrentSigner.getAlgorithm();
            cacheDbIssuer = responseCacher.getIssuer(certId.getIssuer());
            cacheDbSerialNumber = certId.getSerialNumber();
            if (cacheDbIssuer != null) {
                OcspRespWithCacheInfo cachedResp = responseCacher.getOcspResponse(cacheDbIssuer.getId(), cacheDbSerialNumber, cacheDbSigAlg);
                if (cachedResp != null) {
                    boolean granted = license.grant(cacheDbIssuer.getCert().getSubjectRfc4519Text());
                    if (granted) {
                        return cachedResp;
                    } else {
                        LOG.error("Not granted, new license needed");
                        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
                    }
                }
            } else if (master) {
                // store the issuer certificate in cache database.
                X509Cert issuerCert = null;
                for (OcspStore store : responder.getStores()) {
                    issuerCert = store.getIssuerCert(certId.getIssuer());
                    if (issuerCert != null) {
                        break;
                    }
                }
                if (issuerCert != null) {
                    cacheDbIssuer = responseCacher.storeIssuer(issuerCert);
                }
            }
            if (cacheDbIssuer == null) {
                canCacheDb = false;
            }
        }
        ResponderID responderId = signer.getResponderId(repOpt.isResponderIdByName());
        OCSPRespBuilder builder = new OCSPRespBuilder(responderId);
        boolean unknownAsRevoked = false;
        AtomicBoolean unknownAsRevoked0 = new AtomicBoolean(false);
        for (CertID certID : requestList) {
            OcspRespWithCacheInfo failureOcspResp = processCertReq(unknownAsRevoked0, certID, builder, responder, reqOpt, repOpt, repControl);
            if (failureOcspResp != null) {
                return failureOcspResp;
            }
            if (unknownAsRevoked0.get()) {
                unknownAsRevoked = true;
            }
        }
        if (unknownAsRevoked && repControl.includeExtendedRevokeExtension) {
            respExtensions.add(extension_pkix_ocsp_extendedRevoke);
        }
        if (!respExtensions.isEmpty()) {
            builder.setResponseExtensions(new Extensions(respExtensions));
        }
        TaggedCertSequence certsInResp;
        EmbedCertsMode certsMode = repOpt.getEmbedCertsMode();
        if (certsMode == EmbedCertsMode.SIGNER) {
            certsInResp = signer.getSequenceOfCert();
        } else if (certsMode == EmbedCertsMode.NONE) {
            certsInResp = null;
        } else {
            // certsMode == EmbedCertsMode.SIGNER_AND_CA
            certsInResp = signer.getSequenceOfCertChain();
        }
        Date producedAt = new Date();
        byte[] encodeOcspResponse;
        try {
            encodeOcspResponse = builder.buildOCSPResponse(concurrentSigner, certsInResp, producedAt);
        } catch (NoIdleSignerException ex) {
            return unsuccesfulOCSPRespMap.get(OcspResponseStatus.tryLater);
        } catch (OCSPException ex) {
            LogUtil.error(LOG, ex, "answer() basicOcspBuilder.build");
            return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
        }
        long producedAtSeconds = producedAt.getTime() / 1000;
        // cache response in database
        if (canCacheDb && repControl.canCacheInfo) {
            // Don't cache the response with status UNKNOWN, since this may result in DDoS
            // of storage
            responseCacher.storeOcspResponse(cacheDbIssuer.getId(), cacheDbSerialNumber, producedAtSeconds, repControl.cacheNextUpdate, cacheDbSigAlg, encodeOcspResponse);
        }
        if (viaGet && repControl.canCacheInfo) {
            ResponseCacheInfo cacheInfo = new ResponseCacheInfo(producedAtSeconds);
            if (repControl.cacheNextUpdate != Long.MAX_VALUE) {
                cacheInfo.setNextUpdate(repControl.cacheNextUpdate);
            }
            return new OcspRespWithCacheInfo(encodeOcspResponse, cacheInfo);
        } else {
            return new OcspRespWithCacheInfo(encodeOcspResponse, null);
        }
    } catch (Throwable th) {
        LogUtil.error(LOG, th);
        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.internalError);
    }
}
Also used : AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) ASN1InputStream(org.bouncycastle.asn1.ASN1InputStream) IssuerEntry(org.xipki.ocsp.server.store.IssuerEntry) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) EmbedCertsMode(org.xipki.ocsp.server.OcspServerConf.EmbedCertsMode) ResponseCacheInfo(org.xipki.ocsp.api.OcspRespWithCacheInfo.ResponseCacheInfo) BigInteger(java.math.BigInteger) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 53 with ASN1InputStream

use of com.github.zhenwei.core.asn1.ASN1InputStream in project android_packages_apps_Settings by SudaMod.

the class CredentialStorage method isHardwareBackedKey.

private boolean isHardwareBackedKey(byte[] keyData) {
    try {
        final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData));
        final PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
        final String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
        final String algName = new AlgorithmId(new ObjectIdentifier(algOid)).getName();
        return KeyChain.isBoundKeyAlgorithm(algName);
    } catch (IOException e) {
        Log.e(TAG, "Failed to parse key data");
        return false;
    }
}
Also used : ASN1InputStream(com.android.org.bouncycastle.asn1.ASN1InputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) AlgorithmId(sun.security.x509.AlgorithmId) IOException(java.io.IOException) PrivateKeyInfo(com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo) ObjectIdentifier(sun.security.util.ObjectIdentifier)

Example 54 with ASN1InputStream

use of com.github.zhenwei.core.asn1.ASN1InputStream in project BiglyBT by BiglySoftware.

the class X509NameEntryConverter method convertHexEncoded.

/**
 * Convert an inline encoded hex string rendition of an ASN.1
 * object back into its corresponding ASN.1 object.
 *
 * @param str the hex encoded object
 * @param off the index at which the encoding starts
 * @return the decoded object
 */
protected DERObject convertHexEncoded(String str, int off) throws IOException {
    str = Strings.toLowerCase(str);
    byte[] data = new byte[(str.length() - off) / 2];
    for (int index = 0; index != data.length; index++) {
        char left = str.charAt((index * 2) + off);
        char right = str.charAt((index * 2) + off + 1);
        if (left < 'a') {
            data[index] = (byte) ((left - '0') << 4);
        } else {
            data[index] = (byte) ((left - 'a' + 10) << 4);
        }
        if (right < 'a') {
            data[index] |= (byte) (right - '0');
        } else {
            data[index] |= (byte) (right - 'a' + 10);
        }
    }
    ASN1InputStream aIn = new ASN1InputStream(data);
    return aIn.readObject();
}
Also used : ASN1InputStream(org.gudy.bouncycastle.asn1.ASN1InputStream)

Example 55 with ASN1InputStream

use of com.github.zhenwei.core.asn1.ASN1InputStream in project BiglyBT by BiglySoftware.

the class Dump method main.

public static void main(String[] args) throws Exception {
    FileInputStream fIn = new FileInputStream(args[0]);
    ASN1InputStream bIn = new ASN1InputStream(fIn);
    Object obj = null;
    while ((obj = bIn.readObject()) != null) {
        System.out.println(ASN1Dump.dumpAsString(obj));
    }
}
Also used : ASN1InputStream(org.gudy.bouncycastle.asn1.ASN1InputStream) FileInputStream(java.io.FileInputStream)

Aggregations

ASN1InputStream (org.bouncycastle.asn1.ASN1InputStream)171 IOException (java.io.IOException)142 ByteArrayInputStream (java.io.ByteArrayInputStream)76 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)64 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)42 ASN1Primitive (org.bouncycastle.asn1.ASN1Primitive)38 DEROctetString (org.bouncycastle.asn1.DEROctetString)38 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)33 ASN1InputStream (com.github.zhenwei.core.asn1.ASN1InputStream)32 BigInteger (java.math.BigInteger)32 CertificateException (java.security.cert.CertificateException)31 X509Certificate (java.security.cert.X509Certificate)29 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)28 CertificateParsingException (java.security.cert.CertificateParsingException)27 Enumeration (java.util.Enumeration)27 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)26 InvalidKeyException (java.security.InvalidKeyException)25 CertificateEncodingException (java.security.cert.CertificateEncodingException)25 CRLException (java.security.cert.CRLException)24 NoSuchProviderException (java.security.NoSuchProviderException)22