Search in sources :

Example 31 with DerValue

use of sun.security.util.DerValue in project Bytecoder by mirkosertic.

the class PKCS12KeyStore method engineLoad.

/**
 * Loads the keystore from the given input stream.
 *
 * <p>If a password is given, it is used to check the integrity of the
 * keystore data. Otherwise, the integrity of the keystore is not checked.
 *
 * @param stream the input stream from which the keystore is loaded
 * @param password the (optional) password used to check the integrity of
 * the keystore.
 *
 * @exception IOException if there is an I/O or format problem with the
 * keystore data
 * @exception NoSuchAlgorithmException if the algorithm used to check
 * the integrity of the keystore cannot be found
 * @exception CertificateException if any of the certificates in the
 * keystore could not be loaded
 */
public synchronized void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {
    DataInputStream dis;
    CertificateFactory cf = null;
    ByteArrayInputStream bais = null;
    byte[] encoded = null;
    if (stream == null)
        return;
    // reset the counter
    counter = 0;
    DerValue val = new DerValue(stream);
    DerInputStream s = val.toDerInputStream();
    int version = s.getInteger();
    if (version != VERSION_3) {
        throw new IOException("PKCS12 keystore not in version 3 format");
    }
    entries.clear();
    /*
         * Read the authSafe.
         */
    byte[] authSafeData;
    ContentInfo authSafe = new ContentInfo(s);
    ObjectIdentifier contentType = authSafe.getContentType();
    if (contentType.equals(ContentInfo.DATA_OID)) {
        authSafeData = authSafe.getData();
    } else /* signed data */
    {
        throw new IOException("public key protected PKCS12 not supported");
    }
    DerInputStream as = new DerInputStream(authSafeData);
    DerValue[] safeContentsArray = as.getSequence(2);
    int count = safeContentsArray.length;
    // reset the counters at the start
    privateKeyCount = 0;
    secretKeyCount = 0;
    certificateCount = 0;
    /*
         * Spin over the ContentInfos.
         */
    for (int i = 0; i < count; i++) {
        byte[] safeContentsData;
        ContentInfo safeContents;
        DerInputStream sci;
        byte[] eAlgId = null;
        sci = new DerInputStream(safeContentsArray[i].toByteArray());
        safeContents = new ContentInfo(sci);
        contentType = safeContents.getContentType();
        safeContentsData = null;
        if (contentType.equals(ContentInfo.DATA_OID)) {
            if (debug != null) {
                debug.println("Loading PKCS#7 data content-type");
            }
            safeContentsData = safeContents.getData();
        } else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) {
            if (password == null) {
                if (debug != null) {
                    debug.println("Warning: skipping PKCS#7 encryptedData" + " content-type - no password was supplied");
                }
                continue;
            }
            if (debug != null) {
                debug.println("Loading PKCS#7 encryptedData content-type");
            }
            DerInputStream edi = safeContents.getContent().toDerInputStream();
            int edVersion = edi.getInteger();
            DerValue[] seq = edi.getSequence(2);
            ObjectIdentifier edContentType = seq[0].getOID();
            eAlgId = seq[1].toByteArray();
            if (!seq[2].isContextSpecific((byte) 0)) {
                throw new IOException("encrypted content not present!");
            }
            byte newTag = DerValue.tag_OctetString;
            if (seq[2].isConstructed())
                newTag |= 0x20;
            seq[2].resetTag(newTag);
            safeContentsData = seq[2].getOctetString();
            // parse Algorithm parameters
            DerInputStream in = seq[1].toDerInputStream();
            ObjectIdentifier algOid = in.getOID();
            AlgorithmParameters algParams = parseAlgParameters(algOid, in);
            while (true) {
                try {
                    // Use JCE
                    SecretKey skey = getPBEKey(password);
                    Cipher cipher = Cipher.getInstance(algOid.toString());
                    cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
                    safeContentsData = cipher.doFinal(safeContentsData);
                    break;
                } catch (Exception e) {
                    if (password.length == 0) {
                        // Retry using an empty password
                        // without a NULL terminator.
                        password = new char[1];
                        continue;
                    }
                    throw new IOException("keystore password was incorrect", new UnrecoverableKeyException("failed to decrypt safe contents entry: " + e));
                }
            }
        } else {
            throw new IOException("public key protected PKCS12" + " not supported");
        }
        DerInputStream sc = new DerInputStream(safeContentsData);
        loadSafeContents(sc, password);
    }
    // The MacData is optional.
    if (password != null && s.available() > 0) {
        MacData macData = new MacData(s);
        try {
            String algName = macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
            // Change SHA-1 to SHA1
            algName = algName.replace("-", "");
            // generate MAC (MAC key is created within JCE)
            Mac m = Mac.getInstance("HmacPBE" + algName);
            PBEParameterSpec params = new PBEParameterSpec(macData.getSalt(), macData.getIterations());
            SecretKey key = getPBEKey(password);
            m.init(key, params);
            m.update(authSafeData);
            byte[] macResult = m.doFinal();
            if (debug != null) {
                debug.println("Checking keystore integrity " + "(MAC algorithm: " + m.getAlgorithm() + ")");
            }
            if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
                throw new UnrecoverableKeyException("Failed PKCS12" + " integrity checking");
            }
        } catch (Exception e) {
            throw new IOException("Integrity check failed: " + e, e);
        }
    }
    /*
         * Match up private keys with certificate chains.
         */
    PrivateKeyEntry[] list = keyList.toArray(new PrivateKeyEntry[keyList.size()]);
    for (int m = 0; m < list.length; m++) {
        PrivateKeyEntry entry = list[m];
        if (entry.keyId != null) {
            ArrayList<X509Certificate> chain = new ArrayList<X509Certificate>();
            X509Certificate cert = findMatchedCertificate(entry);
            mainloop: while (cert != null) {
                // Check for loops in the certificate chain
                if (!chain.isEmpty()) {
                    for (X509Certificate chainCert : chain) {
                        if (cert.equals(chainCert)) {
                            if (debug != null) {
                                debug.println("Loop detected in " + "certificate chain. Skip adding " + "repeated cert to chain. Subject: " + cert.getSubjectX500Principal().toString());
                            }
                            break mainloop;
                        }
                    }
                }
                chain.add(cert);
                X500Principal issuerDN = cert.getIssuerX500Principal();
                if (issuerDN.equals(cert.getSubjectX500Principal())) {
                    break;
                }
                cert = certsMap.get(issuerDN);
            }
            /* Update existing KeyEntry in entries table */
            if (chain.size() > 0)
                entry.chain = chain.toArray(new Certificate[chain.size()]);
        }
    }
    if (debug != null) {
        if (privateKeyCount > 0) {
            debug.println("Loaded " + privateKeyCount + " protected private key(s)");
        }
        if (secretKeyCount > 0) {
            debug.println("Loaded " + secretKeyCount + " protected secret key(s)");
        }
        if (certificateCount > 0) {
            debug.println("Loaded " + certificateCount + " certificate(s)");
        }
    }
    certEntries.clear();
    certsMap.clear();
    keyList.clear();
}
Also used : CertificateFactory(java.security.cert.CertificateFactory) UnrecoverableKeyException(java.security.UnrecoverableKeyException) ContentInfo(sun.security.pkcs.ContentInfo) DerValue(sun.security.util.DerValue) DerInputStream(sun.security.util.DerInputStream) PBEParameterSpec(javax.crypto.spec.PBEParameterSpec) ObjectIdentifier(sun.security.util.ObjectIdentifier) KeyStoreException(java.security.KeyStoreException) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) UnrecoverableKeyException(java.security.UnrecoverableKeyException) UnrecoverableEntryException(java.security.UnrecoverableEntryException) DestroyFailedException(javax.security.auth.DestroyFailedException) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) Mac(javax.crypto.Mac) X509Certificate(java.security.cert.X509Certificate) SecretKey(javax.crypto.SecretKey) X500Principal(javax.security.auth.x500.X500Principal) Cipher(javax.crypto.Cipher) AlgorithmParameters(java.security.AlgorithmParameters)

Example 32 with DerValue

use of sun.security.util.DerValue in project Bytecoder by mirkosertic.

the class KeyProtector method recover.

/*
     * Recovers the plaintext version of the given key (in protected format),
     * using the password provided at construction time.
     */
public Key recover(EncryptedPrivateKeyInfo encrInfo) throws UnrecoverableKeyException {
    int i;
    byte[] digest;
    int numRounds;
    // offset in xorKey where next digest will be stored
    int xorOffset;
    // the length of the encrpyted key
    int encrKeyLen;
    // do we support the algorithm?
    AlgorithmId encrAlg = encrInfo.getAlgorithm();
    if (!(encrAlg.getOID().toString().equals(KEY_PROTECTOR_OID))) {
        throw new UnrecoverableKeyException("Unsupported key protection " + "algorithm");
    }
    byte[] protectedKey = encrInfo.getEncryptedData();
    /*
         * Get the salt associated with this key (the first SALT_LEN bytes of
         * <code>protectedKey</code>)
         */
    byte[] salt = new byte[SALT_LEN];
    System.arraycopy(protectedKey, 0, salt, 0, SALT_LEN);
    // Determine the number of digest rounds
    encrKeyLen = protectedKey.length - SALT_LEN - DIGEST_LEN;
    numRounds = encrKeyLen / DIGEST_LEN;
    if ((encrKeyLen % DIGEST_LEN) != 0)
        numRounds++;
    // Get the encrypted key portion and store it in "encrKey"
    byte[] encrKey = new byte[encrKeyLen];
    System.arraycopy(protectedKey, SALT_LEN, encrKey, 0, encrKeyLen);
    // Set up the byte array which will be XORed with "encrKey"
    byte[] xorKey = new byte[encrKey.length];
    // Compute the digests, and store them in "xorKey"
    for (i = 0, xorOffset = 0, digest = salt; i < numRounds; i++, xorOffset += DIGEST_LEN) {
        md.update(passwdBytes);
        md.update(digest);
        digest = md.digest();
        md.reset();
        // Copy the digest into "xorKey"
        if (i < numRounds - 1) {
            System.arraycopy(digest, 0, xorKey, xorOffset, digest.length);
        } else {
            System.arraycopy(digest, 0, xorKey, xorOffset, xorKey.length - xorOffset);
        }
    }
    // XOR "encrKey" with "xorKey", and store the result in "plainKey"
    byte[] plainKey = new byte[encrKey.length];
    for (i = 0; i < plainKey.length; i++) {
        plainKey[i] = (byte) (encrKey[i] ^ xorKey[i]);
    }
    /*
         * Check the integrity of the recovered key by concatenating it with
         * the password, digesting the concatenation, and comparing the
         * result of the digest operation with the digest provided at the end
         * of <code>protectedKey</code>. If the two digest values are
         * different, throw an exception.
         */
    md.update(passwdBytes);
    Arrays.fill(passwdBytes, (byte) 0x00);
    passwdBytes = null;
    md.update(plainKey);
    digest = md.digest();
    md.reset();
    for (i = 0; i < digest.length; i++) {
        if (digest[i] != protectedKey[SALT_LEN + encrKeyLen + i]) {
            throw new UnrecoverableKeyException("Cannot recover key");
        }
    }
    // which in turn parses the key material.
    try {
        return PKCS8Key.parseKey(new DerValue(plainKey));
    } catch (IOException ioe) {
        throw new UnrecoverableKeyException(ioe.getMessage());
    }
}
Also used : UnrecoverableKeyException(java.security.UnrecoverableKeyException) AlgorithmId(sun.security.x509.AlgorithmId) DerValue(sun.security.util.DerValue) IOException(java.io.IOException)

Example 33 with DerValue

use of sun.security.util.DerValue in project Bytecoder by mirkosertic.

the class VerifierWrapper method getServername.

/*
     * Extract the name of the SSL server from the certificate.
     *
     * Note this code is essentially a subset of the hostname extraction
     * code in HostnameChecker.
     */
private static String getServername(X509Certificate peerCert) {
    try {
        // compare to subjectAltNames if dnsName is present
        Collection<List<?>> subjAltNames = peerCert.getSubjectAlternativeNames();
        if (subjAltNames != null) {
            for (Iterator<List<?>> itr = subjAltNames.iterator(); itr.hasNext(); ) {
                List<?> next = itr.next();
                if (((Integer) next.get(0)).intValue() == 2) {
                    // compare dNSName with host in url
                    String dnsName = ((String) next.get(1));
                    return dnsName;
                }
            }
        }
        // else check against common name in the subject field
        X500Name subject = HostnameChecker.getSubjectX500Name(peerCert);
        DerValue derValue = subject.findMostSpecificAttribute(X500Name.commonName_oid);
        if (derValue != null) {
            try {
                String name = derValue.getAsString();
                return name;
            } catch (IOException e) {
            // ignore
            }
        }
    } catch (java.security.cert.CertificateException e) {
    // ignore
    }
    return null;
}
Also used : DerValue(sun.security.util.DerValue) List(java.util.List) java.security.cert(java.security.cert) X500Name(sun.security.x509.X500Name) IOException(java.io.IOException)

Example 34 with DerValue

use of sun.security.util.DerValue in project Bytecoder by mirkosertic.

the class X400Address method encode.

/**
 * Encode the X400 name into the DerOutputStream.
 *
 * @param out the DER stream to encode the X400Address to.
 * @exception IOException on encoding errors.
 */
public void encode(DerOutputStream out) throws IOException {
    DerValue derValue = new DerValue(nameValue);
    out.putDerValue(derValue);
}
Also used : DerValue(sun.security.util.DerValue)

Example 35 with DerValue

use of sun.security.util.DerValue in project j2objc by google.

the class PKCS9Attributes method decode.

/**
     * Decode this set of PKCS9 attributes from the contents of its
     * DER encoding. Ignores unsupported attributes when directed.
     *
     * @param in
     * the contents of the DER encoding of the attribute set.
     *
     * @exception IOException
     * on i/o error, encoding syntax error, unacceptable or
     * unsupported attribute, or duplicate attribute.
     */
private byte[] decode(DerInputStream in) throws IOException {
    DerValue val = in.getDerValue();
    // save the DER encoding with its proper tag byte.
    byte[] derEncoding = val.toByteArray();
    derEncoding[0] = DerValue.tag_SetOf;
    DerInputStream derIn = new DerInputStream(derEncoding);
    DerValue[] derVals = derIn.getSet(3, true);
    PKCS9Attribute attrib;
    ObjectIdentifier oid;
    boolean reuseEncoding = true;
    for (int i = 0; i < derVals.length; i++) {
        try {
            attrib = new PKCS9Attribute(derVals[i]);
        } catch (ParsingException e) {
            if (ignoreUnsupportedAttributes) {
                // cannot reuse supplied DER encoding
                reuseEncoding = false;
                // skip
                continue;
            } else {
                throw e;
            }
        }
        oid = attrib.getOID();
        if (attributes.get(oid) != null)
            throw new IOException("Duplicate PKCS9 attribute: " + oid);
        if (permittedAttributes != null && !permittedAttributes.containsKey(oid))
            throw new IOException("Attribute " + oid + " not permitted in this attribute set");
        attributes.put(oid, attrib);
    }
    return reuseEncoding ? derEncoding : generateDerEncoding();
}
Also used : DerValue(sun.security.util.DerValue) DerInputStream(sun.security.util.DerInputStream) IOException(java.io.IOException) ObjectIdentifier(sun.security.util.ObjectIdentifier)

Aggregations

DerValue (sun.security.util.DerValue)72 DerInputStream (sun.security.util.DerInputStream)26 IOException (java.io.IOException)25 ObjectIdentifier (sun.security.util.ObjectIdentifier)17 CertificateException (java.security.cert.CertificateException)12 DerOutputStream (sun.security.util.DerOutputStream)11 UnrecoverableKeyException (java.security.UnrecoverableKeyException)10 BigInteger (java.math.BigInteger)9 KeyStoreException (java.security.KeyStoreException)9 X509Certificate (java.security.cert.X509Certificate)9 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)8 UnrecoverableEntryException (java.security.UnrecoverableEntryException)8 CertificateFactory (java.security.cert.CertificateFactory)7 DestroyFailedException (javax.security.auth.DestroyFailedException)6 X500Principal (javax.security.auth.x500.X500Principal)6 X509CertImpl (sun.security.x509.X509CertImpl)6 AlgorithmId (sun.security.x509.AlgorithmId)5 AlgorithmParameters (java.security.AlgorithmParameters)4 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)4 KeyFactory (java.security.KeyFactory)4