common.crypto.PKCS10 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
package com.unbound.common.crypto;
import javax.security.auth.x500.X500Principal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class PKCS10
{
private PublicKey publicKey;
private String[] dns;
private InetAddress[] ip;
private String challengePassword;
private byte[] signature;
private String signHashOid;
private Map subject = new HashMap<>();
public PKCS10(PublicKey publicKey)
{
this.publicKey = publicKey;
}
public PKCS10(byte[] der) throws InvalidKeySpecException, UnknownHostException
{
DER.Parser parser = new DER.Parser(der);
parser.beginSequence(); // CertificationRequest
parser.beginSequence(); // CertificationRequestInfo
parser.getBigInteger(); // version 0
parser.beginSequence(); // subject
for (;;)
{
parser.beginSet();
parser.beginSequence();
String oid = parser.getOid();
String value = parser.getString();
subject.put(X509.getRdnFromOid(oid), value);
parser.end();
parser.end();
if (parser.endOfBlock()) break;
}
parser.end();
byte[] publicKeyEncoded = parser.getFullTag();
if (parser.isTag((byte)0xa0))
{
parser.begin((byte)0xa0);
parser.beginSequence();
parser.checkOid("1.2.840.113549.1.9.14"); // certificate extensions
parser.beginSet();
parser.beginSequence();
parser.beginSequence();
parser.checkOid("2.5.29.17"); // subject alternative name
parser.beginOctetString();
parser.beginSequence();
ArrayList dnsList = new ArrayList();
while (parser.isTag((byte)0x82)) dnsList.add(parser.getString((byte)0x82));
if (!dnsList.isEmpty()) { dns = new String[dnsList.size()]; dnsList.toArray(dns); }
ArrayList ipList = new ArrayList();
while (parser.isTag((byte)0x87)) ipList.add(InetAddress.getByAddress(parser.getTagBytes((byte)0x87)));
if (!ipList.isEmpty()) { ip = new InetAddress[ipList.size()]; ipList.toArray(ip); }
parser.end();
parser.end();
parser.end();
parser.end();
parser.end();
parser.end();
if (parser.isTag(DER.TAG_SEQUENCE))
{
parser.beginSequence();
parser.checkOid("1.2.840.113549.1.9.7"); // challenge password
parser.beginSet();
challengePassword = parser.getString();
parser.end();
parser.end();
}
parser.end();
}
parser.end();
parser.beginSequence(); // AlgorithmIdentifier
signHashOid = parser.getOid();
parser.skipNull();
parser.end();
signature = parser.getBitString(); // signature
parser.end();
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyEncoded);
KeyFactory kf = SystemProvider.KeyFactory.getInstance("RSA");
try { publicKey = kf.generatePublic(spec); }
catch (InvalidKeySpecException e)
{
kf = SystemProvider.KeyFactory.getInstance("ECDSA");
publicKey = kf.generatePublic(spec);
}
}
public PublicKey getPublicKey() { return publicKey; }
public X500Principal getSubject()
{
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : subject.entrySet())
{
if (sb.length()>0) sb.append(", ");
sb.append(entry.getKey());
sb.append("=");
sb.append(entry.getValue());
}
return new X500Principal(sb.toString());
}
public void verifySignature() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException
{
Signature sig;
String sigName;
String hashType;
if (publicKey.getAlgorithm().equalsIgnoreCase("RSA"))
{
if (signHashOid.equalsIgnoreCase(X509.OID_RSA_WITH_SHA256)) hashType = "SHA256";
else if (signHashOid.equalsIgnoreCase(X509.OID_RSA_WITH_SHA1)) hashType = "SHA1";
else throw new IllegalArgumentException("Unsupported hash type");
sigName = hashType + "withRSA";
}
else
{
if (signHashOid.equalsIgnoreCase(X509.OID_ECDSA_WITH_SHA256)) hashType = "SHA256";
else if (signHashOid.equalsIgnoreCase(X509.OID_ECDSA_WITH_SHA1)) hashType = "SHA1";
else throw new IllegalArgumentException("Unsupported hash type");
sigName = hashType + "withECDSA";
}
sig = Signature.getInstance(sigName);
sig.initVerify(publicKey);
sig.update(toBeSigned());
boolean ok = sig.verify(signature);
if (!ok) throw new SignatureException("Verification failed");
}
public void setAlternativeSubjectName(String[] dns, InetAddress[] ip)
{
this.dns = dns;
this.ip = ip;
}
public void setSubjectName(String type, String name)
{
subject.put(type, name);
}
public void setChallengePassword(String challengePassword)
{
this.challengePassword = challengePassword;
}
public void sign(PrivateKey key, String hashType) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException
{
Signature sig;
String sigName;
if (key.getAlgorithm().equalsIgnoreCase("RSA"))
{
if (hashType.equals("SHA256")) signHashOid = X509.OID_RSA_WITH_SHA256;
else if (hashType.equals("SHA1")) signHashOid = X509.OID_RSA_WITH_SHA1;
else throw new IllegalArgumentException("Unsupported hash type");
sigName = hashType + "withRSA";
}
else
{
if (hashType.equals("SHA256")) signHashOid = X509.OID_ECDSA_WITH_SHA256;
else if (hashType.equals("SHA1")) signHashOid = X509.OID_ECDSA_WITH_SHA1;
else throw new IllegalArgumentException("Unsupported hash type");
sigName = hashType + "withECDSA";
}
sig = Signature.getInstance(sigName);
sig.initSign(key);
sig.update(toBeSigned());
signature = sig.sign();
}
private DER.Builder encodeCertificationRequestInfo(DER.Builder builder)
{
builder.beginSequence(). // CertificationRequestInfo
addInteger(0); // version 0
X509.encode(builder, subject).
add(publicKey.getEncoded());
if (challengePassword!=null || dns!=null || ip!=null)
{
builder.begin((byte)0xa0);
if (dns!=null || ip!=null)
{
builder.beginSequence().
addOid("1.2.840.113549.1.9.14"). // certificate extensions
beginSet().
beginSequence().
beginSequence().
addOid("2.5.29.17"). // subject alternative name
beginOctetString().
beginSequence();
if (dns!=null) for (String s : dns) builder.add((byte)0x82, s);
if (ip!=null) for (InetAddress i : ip) builder.add((byte)0x87, i.getAddress());
builder.end().
end().
end().
end().
end().
end();
}
if (challengePassword!=null)
{
builder.beginSequence().
addOid("1.2.840.113549.1.9.7"). // challenge password
beginSet().
add(DER.TAG_PRINTABLE_STRING, challengePassword).
end().
end();
}
builder.end();
}
return builder.end();
}
private byte[] toBeSigned()
{
return encodeCertificationRequestInfo(new DER.Builder()).toByteArray();
}
public byte[] exportDer()
{
DER.Builder builder = new DER.Builder();
builder.beginSequence(); // CertificationRequest
encodeCertificationRequestInfo(builder).
beginSequence(). // AlgorithmIdentifier
addOid(signHashOid).
addNull().
end().
addBitString(signature). // signature
end();
return builder.toByteArray();
}
}