Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #69-ssh-pubkey-pem #70

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/main/java/org/cryptacular/KeyDecoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular;

/**
* Contract interface for converting encoded bytes to an object.
*
* @param <T> Type of object to produce on decode.
*
* @author Middleware Services
*/
public interface KeyDecoder<T>
{

/**
* Produces an object from an encoded representation.
*
* @param encoded data.
* @param args Additional data required to perform decoding.
*
* @return Decoded object.
*
* @throws EncodingException on encoding errors.
*/
T decode(byte[] encoded, Object... args) throws EncodingException;

}
16 changes: 2 additions & 14 deletions src/main/java/org/cryptacular/asn/ASN1Decoder.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.asn;

import org.cryptacular.EncodingException;
import org.cryptacular.KeyDecoder;

/**
* Strategy interface for converting encoded ASN.1 bytes to an object.
Expand All @@ -10,18 +10,6 @@
*
* @author Middleware Services
*/
public interface ASN1Decoder<T>
public interface ASN1Decoder<T> extends KeyDecoder<T>
{

/**
* Produces an object from an encoded representation.
*
* @param encoded ASN.1 encoded data.
* @param args Additional data required to perform decoding.
*
* @return Decoded object.
*
* @throws EncodingException on encoding errors.
*/
T decode(byte[] encoded, Object... args) throws EncodingException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.cryptacular.EncodingException;
import org.cryptacular.io.pem.PemObject;
import org.cryptacular.pbe.OpenSSLAlgorithm;
import org.cryptacular.pbe.OpenSSLEncryptionScheme;
import org.cryptacular.util.ByteUtil;
Expand All @@ -36,7 +37,7 @@ public class OpenSSLPrivateKeyDecoder extends AbstractPrivateKeyDecoder<Asymmetr
protected byte[] decryptKey(final byte[] encrypted, final char[] password)
{
final String pem = new String(encrypted, ByteUtil.ASCII_CHARSET);
final int start = pem.indexOf(PemUtil.DEK_INFO);
final int start = pem.indexOf(PemObject.RFC1421_HEADER_FIELD_DEK_INFO);
final int eol = pem.indexOf('\n', start);
final String[] dekInfo = pem.substring(start + 10, eol).split(",");
final String alg = dekInfo[0];
Expand Down
41 changes: 40 additions & 1 deletion src/main/java/org/cryptacular/asn/PublicKeyDecoder.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.asn;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.cryptacular.EncodingException;
import org.cryptacular.io.pem.PemObject;
import org.cryptacular.ssh.SSHPublicKeyDecoder;
import org.cryptacular.util.ByteUtil;
import org.cryptacular.util.PemUtil;

/**
Expand All @@ -21,11 +27,44 @@ public AsymmetricKeyParameter decode(final byte[] encoded, final Object... args)
{
try {
if (PemUtil.isPem(encoded)) {
return PublicKeyFactory.createKey(PemUtil.decode(encoded));
return decodePem(encoded, args);
} else if (SSHPublicKeyDecoder.isRFC4253EncodedPublicKey(encoded)) {
return new SSHPublicKeyDecoder().decode(new String(encoded, ByteUtil.ASCII_CHARSET));
}
return PublicKeyFactory.createKey(new ASN1InputStream(encoded).readObject().getEncoded());
} catch (IOException e) {
throw new EncodingException("ASN.1 decoding error", e);
}
}


/**
* Decodes PEM formats.
*
* @param encoded data.
* @param args Additional data required to perform decoding.
*
* @return Decoded object.
*
* @throws EncodingException on encoding errors.
*/
private AsymmetricKeyParameter decodePem(final byte[] encoded, final Object... args)
throws EncodingException
{
final PemObject pem;
try {
pem = PemUtil.read(new BufferedReader(
new InputStreamReader(new ByteArrayInputStream(encoded))));
} catch (IllegalArgumentException | IOException ex) {
throw new EncodingException("Could not parse PEM data", ex);
}
if (PemObject.Format.RFC4716.equals(pem.getDescriptor().getFormat())) {
return new SSHPublicKeyDecoder().decode(pem.getContent(), args);
}
try {
return PublicKeyFactory.createKey(pem.getContent());
} catch (IOException ex) {
throw new EncodingException("Could not decode key", ex);
}
}
}
Loading