use of sun.security.util.DerValue in project Bytecoder by mirkosertic.
the class TimestampToken method parse.
/*
* Parses the timestamp token info.
*
* @param timestampTokenInfo A buffer containing an ASN.1 BER encoded
* TSTInfo.
* @throws IOException The exception is thrown if a problem is encountered
* while parsing.
*/
private void parse(byte[] timestampTokenInfo) throws IOException {
DerValue tstInfo = new DerValue(timestampTokenInfo);
if (tstInfo.tag != DerValue.tag_Sequence) {
throw new IOException("Bad encoding for timestamp token info");
}
// Parse version
version = tstInfo.data.getInteger();
// Parse policy
policy = tstInfo.data.getOID();
// Parse messageImprint
DerValue messageImprint = tstInfo.data.getDerValue();
hashAlgorithm = AlgorithmId.parse(messageImprint.data.getDerValue());
hashedMessage = messageImprint.data.getOctetString();
// Parse serialNumber
serialNumber = tstInfo.data.getBigInteger();
// Parse genTime
genTime = tstInfo.data.getGeneralizedTime();
// Parse optional elements, if present
while (tstInfo.data.available() > 0) {
DerValue d = tstInfo.data.getDerValue();
if (d.tag == DerValue.tag_Integer) {
// must be the nonce
nonce = d.getBigInteger();
break;
}
// Additional fields:
// Parse accuracy
// Parse ordering
// Parse tsa
// Parse extensions
}
}
use of sun.security.util.DerValue in project Bytecoder by mirkosertic.
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();
}
use of sun.security.util.DerValue in project Bytecoder by mirkosertic.
the class PKCS12KeyStore method engineStore.
/**
* Stores this keystore to the given output stream, and protects its
* integrity with the given password.
*
* @param stream the output stream to which this keystore is written.
* @param password the password to generate the keystore integrity check
*
* @exception IOException if there was an I/O problem with data
* @exception NoSuchAlgorithmException if the appropriate data integrity
* algorithm could not be found
* @exception CertificateException if any of the certificates included in
* the keystore data could not be stored
*/
public synchronized void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {
// password is mandatory when storing
if (password == null) {
throw new IllegalArgumentException("password can't be null");
}
// -- Create PFX
DerOutputStream pfx = new DerOutputStream();
// PFX version (always write the latest version)
DerOutputStream version = new DerOutputStream();
version.putInteger(VERSION_3);
byte[] pfxVersion = version.toByteArray();
pfx.write(pfxVersion);
// -- Create AuthSafe
DerOutputStream authSafe = new DerOutputStream();
// -- Create ContentInfos
DerOutputStream authSafeContentInfo = new DerOutputStream();
// -- create safeContent Data ContentInfo
if (privateKeyCount > 0 || secretKeyCount > 0) {
if (debug != null) {
debug.println("Storing " + (privateKeyCount + secretKeyCount) + " protected key(s) in a PKCS#7 data content-type");
}
byte[] safeContentData = createSafeContent();
ContentInfo dataContentInfo = new ContentInfo(safeContentData);
dataContentInfo.encode(authSafeContentInfo);
}
// -- create EncryptedContentInfo
if (certificateCount > 0) {
if (debug != null) {
debug.println("Storing " + certificateCount + " certificate(s) in a PKCS#7 encryptedData content-type");
}
byte[] encrData = createEncryptedData(password);
ContentInfo encrContentInfo = new ContentInfo(ContentInfo.ENCRYPTED_DATA_OID, new DerValue(encrData));
encrContentInfo.encode(authSafeContentInfo);
}
// wrap as SequenceOf ContentInfos
DerOutputStream cInfo = new DerOutputStream();
cInfo.write(DerValue.tag_SequenceOf, authSafeContentInfo);
byte[] authenticatedSafe = cInfo.toByteArray();
// Create Encapsulated ContentInfo
ContentInfo contentInfo = new ContentInfo(authenticatedSafe);
contentInfo.encode(authSafe);
byte[] authSafeData = authSafe.toByteArray();
pfx.write(authSafeData);
// -- MAC
byte[] macData = calculateMac(password, authenticatedSafe);
pfx.write(macData);
// write PFX to output stream
DerOutputStream pfxout = new DerOutputStream();
pfxout.write(DerValue.tag_Sequence, pfx);
byte[] pfxData = pfxout.toByteArray();
stream.write(pfxData);
stream.flush();
}
use of sun.security.util.DerValue in project Bytecoder by mirkosertic.
the class PKCS12KeyStore method engineGetKey.
/**
* Returns the key associated with the given alias, using the given
* password to recover it.
*
* @param alias the alias name
* @param password the password for recovering the key
*
* @return the requested key, or null if the given alias does not exist
* or does not identify a <i>key entry</i>.
*
* @exception NoSuchAlgorithmException if the algorithm for recovering the
* key cannot be found
* @exception UnrecoverableKeyException if the key cannot be recovered
* (e.g., the given password is wrong).
*/
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
Key key = null;
if (entry == null || (!(entry instanceof KeyEntry))) {
return null;
}
// get the encoded private key or secret key
byte[] encrBytes = null;
if (entry instanceof PrivateKeyEntry) {
encrBytes = ((PrivateKeyEntry) entry).protectedPrivKey;
} else if (entry instanceof SecretKeyEntry) {
encrBytes = ((SecretKeyEntry) entry).protectedSecretKey;
} else {
throw new UnrecoverableKeyException("Error locating key");
}
byte[] encryptedKey;
AlgorithmParameters algParams;
ObjectIdentifier algOid;
try {
// get the encrypted private key
EncryptedPrivateKeyInfo encrInfo = new EncryptedPrivateKeyInfo(encrBytes);
encryptedKey = encrInfo.getEncryptedData();
// parse Algorithm parameters
DerValue val = new DerValue(encrInfo.getAlgorithm().encode());
DerInputStream in = val.toDerInputStream();
algOid = in.getOID();
algParams = parseAlgParameters(algOid, in);
} catch (IOException ioe) {
UnrecoverableKeyException uke = new UnrecoverableKeyException("Private key not stored as " + "PKCS#8 EncryptedPrivateKeyInfo: " + ioe);
uke.initCause(ioe);
throw uke;
}
try {
byte[] keyInfo;
while (true) {
try {
// Use JCE
SecretKey skey = getPBEKey(password);
Cipher cipher = Cipher.getInstance(mapPBEParamsToAlgorithm(algOid, algParams));
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
keyInfo = cipher.doFinal(encryptedKey);
break;
} catch (Exception e) {
if (password.length == 0) {
// Retry using an empty password
// without a NULL terminator.
password = new char[1];
continue;
}
throw e;
}
}
/*
* Parse the key algorithm and then use a JCA key factory
* to re-create the key.
*/
DerValue val = new DerValue(keyInfo);
DerInputStream in = val.toDerInputStream();
int i = in.getInteger();
DerValue[] value = in.getSequence(2);
AlgorithmId algId = new AlgorithmId(value[0].getOID());
String keyAlgo = algId.getName();
// decode private key
if (entry instanceof PrivateKeyEntry) {
KeyFactory kfac = KeyFactory.getInstance(keyAlgo);
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(keyInfo);
key = kfac.generatePrivate(kspec);
if (debug != null) {
debug.println("Retrieved a protected private key (" + key.getClass().getName() + ") at alias '" + alias + "'");
}
// decode secret key
} else {
byte[] keyBytes = in.getOctetString();
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, keyAlgo);
// Special handling required for PBE: needs a PBEKeySpec
if (keyAlgo.startsWith("PBE")) {
SecretKeyFactory sKeyFactory = SecretKeyFactory.getInstance(keyAlgo);
KeySpec pbeKeySpec = sKeyFactory.getKeySpec(secretKeySpec, PBEKeySpec.class);
key = sKeyFactory.generateSecret(pbeKeySpec);
} else {
key = secretKeySpec;
}
if (debug != null) {
debug.println("Retrieved a protected secret key (" + key.getClass().getName() + ") at alias '" + alias + "'");
}
}
} catch (Exception e) {
UnrecoverableKeyException uke = new UnrecoverableKeyException("Get Key failed: " + e.getMessage());
uke.initCause(e);
throw uke;
}
return key;
}
use of sun.security.util.DerValue in project Bytecoder by mirkosertic.
the class PKCS12KeyStore method loadSafeContents.
private void loadSafeContents(DerInputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {
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)) {
PrivateKeyEntry kEntry = new PrivateKeyEntry();
kEntry.protectedPrivKey = bagValue.toByteArray();
bagItem = kEntry;
privateKeyCount++;
} else if (bagId.equals(CertBag_OID)) {
DerInputStream cs = new DerInputStream(bagValue.toByteArray());
DerValue[] certValues = cs.getSequence(2);
ObjectIdentifier certId = certValues[0].getOID();
if (!certValues[1].isContextSpecific((byte) 0)) {
throw new IOException("unsupported PKCS12 cert value type " + certValues[1].tag);
}
DerValue certValue = certValues[1].data.getDerValue();
CertificateFactory cf = CertificateFactory.getInstance("X509");
X509Certificate cert;
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certValue.getOctetString()));
bagItem = cert;
certificateCount++;
} else if (bagId.equals(SecretBag_OID)) {
DerInputStream ss = new DerInputStream(bagValue.toByteArray());
DerValue[] secretValues = ss.getSequence(2);
ObjectIdentifier secretId = secretValues[0].getOID();
if (!secretValues[1].isContextSpecific((byte) 0)) {
throw new IOException("unsupported PKCS12 secret value type " + secretValues[1].tag);
}
DerValue secretValue = secretValues[1].data.getDerValue();
SecretKeyEntry kEntry = new SecretKeyEntry();
kEntry.protectedSecretKey = secretValue.getOctetString();
bagItem = kEntry;
secretKeyCount++;
} else {
if (debug != null) {
debug.println("Unsupported PKCS12 bag type: " + bagId);
}
}
DerValue[] attrSet;
try {
attrSet = sbi.getSet(3);
} catch (IOException e) {
// entry does not have attributes
// Note: CA certs can have no attributes
// OpenSSL generates pkcs12 with no attr for CA certs.
attrSet = null;
}
String alias = null;
byte[] keyId = null;
ObjectIdentifier[] trustedKeyUsage = null;
Set<PKCS12Attribute> attributes = new HashSet<>();
if (attrSet != null) {
for (int j = 0; j < attrSet.length; j++) {
byte[] encoded = attrSet[j].toByteArray();
DerInputStream as = new DerInputStream(encoded);
DerValue[] attrSeq = as.getSequence(2);
ObjectIdentifier attrId = attrSeq[0].getOID();
DerInputStream vs = new DerInputStream(attrSeq[1].toByteArray());
DerValue[] valSet;
try {
valSet = vs.getSet(1);
} catch (IOException e) {
throw new IOException("Attribute " + attrId + " should have a value " + e.getMessage());
}
if (attrId.equals(PKCS9FriendlyName_OID)) {
alias = valSet[0].getBMPString();
} else if (attrId.equals(PKCS9LocalKeyId_OID)) {
keyId = valSet[0].getOctetString();
} else if (attrId.equals(TrustedKeyUsage_OID)) {
trustedKeyUsage = new ObjectIdentifier[valSet.length];
for (int k = 0; k < valSet.length; k++) {
trustedKeyUsage[k] = valSet[k].getOID();
}
} else {
attributes.add(new PKCS12Attribute(encoded));
}
}
}
/*
* As per PKCS12 v1.0 friendlyname (alias) and localKeyId (keyId)
* are optional PKCS12 bagAttributes. But entries in the keyStore
* are identified by their alias. Hence we need to have an
* Unfriendlyname in the alias, if alias is null. The keyId
* attribute is required to match the private key with the
* certificate. If we get a bagItem of type KeyEntry with a
* null keyId, we should skip it entirely.
*/
if (bagItem instanceof KeyEntry) {
KeyEntry entry = (KeyEntry) bagItem;
if (bagItem instanceof PrivateKeyEntry) {
if (keyId == null) {
// associated cert-chain
if (privateKeyCount == 1) {
keyId = "01".getBytes("UTF8");
} else {
continue;
}
}
}
entry.keyId = keyId;
// restore date if it exists
String keyIdStr = new String(keyId, "UTF8");
Date date = null;
if (keyIdStr.startsWith("Time ")) {
try {
date = new Date(Long.parseLong(keyIdStr.substring(5)));
} catch (Exception e) {
date = null;
}
}
if (date == null) {
date = new Date();
}
entry.date = date;
if (bagItem instanceof PrivateKeyEntry) {
keyList.add((PrivateKeyEntry) entry);
}
if (entry.attributes == null) {
entry.attributes = new HashSet<>();
}
entry.attributes.addAll(attributes);
if (alias == null) {
alias = getUnfriendlyName();
}
entry.alias = alias;
entries.put(alias.toLowerCase(Locale.ENGLISH), entry);
} else if (bagItem instanceof X509Certificate) {
X509Certificate cert = (X509Certificate) bagItem;
// associated cert-chain
if ((keyId == null) && (privateKeyCount == 1)) {
// insert localKeyID only for EE cert or self-signed cert
if (i == 0) {
keyId = "01".getBytes("UTF8");
}
}
// Trusted certificate
if (trustedKeyUsage != null) {
if (alias == null) {
alias = getUnfriendlyName();
}
CertEntry certEntry = new CertEntry(cert, keyId, alias, trustedKeyUsage, attributes);
entries.put(alias.toLowerCase(Locale.ENGLISH), certEntry);
} else {
certEntries.add(new CertEntry(cert, keyId, alias));
}
X500Principal subjectDN = cert.getSubjectX500Principal();
if (subjectDN != null) {
if (!certsMap.containsKey(subjectDN)) {
certsMap.put(subjectDN, cert);
}
}
}
}
}
Aggregations