@SuppressWarnings("deprecation") private byte[] fetchPrivateKeyFromBag(byte[] privateKeyInfo) throws IOException, NoSuchAlgorithmException, CertificateException { byte[] returnValue = null; DerValue val = new DerValue(new ByteArrayInputStream(privateKeyInfo)); DerInputStream s = val.toDerInputStream(); int version = s.getInteger(); if (version != 3) { throw new IOException("PKCS12 keystore not in version 3 format"); } /* * 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; /* * 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)) { safeContentsData = safeContents.getData(); } else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) { // The password was used to export the private key from the keychain. // The Keychain won't export the key with encrypted data, so we don't need // to worry about it. continue; } else { throw new IOException("public key protected PKCS12" + " not supported"); } DerInputStream sc = new DerInputStream(safeContentsData); returnValue = extractKeyData(sc); } return returnValue; }
@SuppressWarnings("deprecation") private byte[] extractKeyData(DerInputStream stream) throws IOException, NoSuchAlgorithmException, CertificateException { byte[] returnValue = null; DerValue[] safeBags = stream.getSequence(2); int count = safeBags.length; /* * Spin over the SafeBags. */ for (int i = 0; i < count; i++) { ObjectIdentifier bagId; DerInputStream sbi; DerValue bagValue; Object bagItem = null; sbi = safeBags[i].toDerInputStream(); bagId = sbi.getOID(); bagValue = sbi.getDerValue(); if (!bagValue.isContextSpecific((byte) 0)) { throw new IOException("unsupported PKCS12 bag value type " + bagValue.tag); } bagValue = bagValue.data.getDerValue(); if (bagId.equals(PKCS8ShroudedKeyBag_OID)) { // got what we were looking for. Return it. returnValue = bagValue.toByteArray(); } else { // log error message for "unsupported PKCS12 bag type" System.out.println("Unsupported bag type '" + bagId + "'"); } } return returnValue; }