1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.jce.netscape; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayInputStream; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayOutputStream; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.InvalidKeyException; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.KeyFactory; 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.NoSuchAlgorithmException; 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.NoSuchProviderException; 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.PrivateKey; 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.PublicKey; 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.SecureRandom; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.Signature; 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.SignatureException; 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.spec.InvalidKeySpecException; 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.spec.X509EncodedKeySpec; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Encodable; 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1EncodableVector; 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1InputStream; 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence; 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERBitString; 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERIA5String; 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERObject; 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSequence; 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.AlgorithmIdentifier; 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Handles NetScape certificate request (KEYGEN), these are constructed as: 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <pre><code> 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * SignedPublicKeyAndChallenge ::= SEQUENCE { 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * publicKeyAndChallenge PublicKeyAndChallenge, 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * signatureAlgorithm AlgorithmIdentifier, 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * signature BIT STRING 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * } 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * </pre> 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * PublicKey's encoded-format has to be X.509. 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam **/ 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class NetscapeCertRequest 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends ASN1Encodable 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmIdentifier sigAlg; 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmIdentifier keyAlg; 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte sigBits []; 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String challenge; 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERBitString content; 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PublicKey pubkey ; 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static ASN1Sequence getReq( 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] r) 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(r)); 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return ASN1Sequence.getInstance(aIn.readObject()); 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public NetscapeCertRequest( 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] req) 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this(getReq(req)); 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public NetscapeCertRequest (ASN1Sequence spkac) 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // SignedPublicKeyAndChallenge ::= SEQUENCE { 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // publicKeyAndChallenge PublicKeyAndChallenge, 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // signatureAlgorithm AlgorithmIdentifier, 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // signature BIT STRING 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // } 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (spkac.size() != 3) 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("invalid SPKAC (size):" 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + spkac.size()); 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sigAlg = new AlgorithmIdentifier((ASN1Sequence)spkac 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam .getObjectAt(1)); 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sigBits = ((DERBitString)spkac.getObjectAt(2)).getBytes(); 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // PublicKeyAndChallenge ::= SEQUENCE { 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // spki SubjectPublicKeyInfo, 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // challenge IA5STRING 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // } 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence pkac = (ASN1Sequence)spkac.getObjectAt(0); 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (pkac.size() != 2) 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("invalid PKAC (len): " 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam + pkac.size()); 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam challenge = ((DERIA5String)pkac.getObjectAt(1)).getString(); 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam //this could be dangerous, as ASN.1 decoding/encoding 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam //could potentially alter the bytes 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam content = new DERBitString(pkac); 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SubjectPublicKeyInfo pubkeyinfo = new SubjectPublicKeyInfo( 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam (ASN1Sequence)pkac.getObjectAt(0)); 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString( 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pubkeyinfo).getBytes()); 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keyAlg = pubkeyinfo.getAlgorithmId(); 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pubkey = KeyFactory.getInstance(keyAlg.getObjectId().getId(), "BC") 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam .generatePublic(xspec); 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException(e.toString()); 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public NetscapeCertRequest( 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String challenge, 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmIdentifier signing_alg, 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PublicKey pub_key) throws NoSuchAlgorithmException, 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InvalidKeySpecException, NoSuchProviderException 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.challenge = challenge; 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sigAlg = signing_alg; 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pubkey = pub_key; 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector content_der = new ASN1EncodableVector(); 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam content_der.add(getKeySpec()); 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam //content_der.add(new SubjectPublicKeyInfo(sigAlg, new RSAPublicKeyStructure(pubkey.getModulus(), pubkey.getPublicExponent()).getDERObject())); 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam content_der.add(new DERIA5String(challenge)); 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam content = new DERBitString(new DERSequence(content_der)); 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String getChallenge() 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return challenge; 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void setChallenge(String value) 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam challenge = value; 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public AlgorithmIdentifier getSigningAlgorithm() 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return sigAlg; 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void setSigningAlgorithm(AlgorithmIdentifier value) 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sigAlg = value; 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public AlgorithmIdentifier getKeyAlgorithm() 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return keyAlg; 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void setKeyAlgorithm(AlgorithmIdentifier value) 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keyAlg = value; 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public PublicKey getPublicKey() 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return pubkey; 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void setPublicKey(PublicKey value) 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pubkey = value; 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public boolean verify(String challenge) throws NoSuchAlgorithmException, 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InvalidKeyException, SignatureException, NoSuchProviderException 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!challenge.equals(this.challenge)) 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Verify the signature .. shows the response was generated 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // by someone who knew the associated private key 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Signature sig = Signature.getInstance(sigAlg.getObjectId().getId(), 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam "BC"); 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sig.initVerify(pubkey); 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sig.update(content.getBytes()); 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return sig.verify(sigBits); 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void sign(PrivateKey priv_key) throws NoSuchAlgorithmException, 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InvalidKeyException, SignatureException, NoSuchProviderException, 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InvalidKeySpecException 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sign(priv_key, null); 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void sign(PrivateKey priv_key, SecureRandom rand) 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws NoSuchAlgorithmException, InvalidKeyException, 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SignatureException, NoSuchProviderException, 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InvalidKeySpecException 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Signature sig = Signature.getInstance(sigAlg.getObjectId().getId(), 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam "BC"); 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (rand != null) 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sig.initSign(priv_key, rand); 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sig.initSign(priv_key); 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector pkac = new ASN1EncodableVector(); 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pkac.add(getKeySpec()); 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pkac.add(new DERIA5String(challenge)); 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom sig.update(new DERSequence(pkac).getEncoded(ASN1Encodable.DER)); 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException ioe) 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new SignatureException(ioe.getMessage()); 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam sigBits = sig.sign(); 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private DERObject getKeySpec() throws NoSuchAlgorithmException, 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InvalidKeySpecException, NoSuchProviderException 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ByteArrayOutputStream baos = new ByteArrayOutputStream(); 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERObject obj = null; 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam baos.write(pubkey.getEncoded()); 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam baos.close(); 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1InputStream derin = new ASN1InputStream( 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new ByteArrayInputStream(baos.toByteArray())); 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam obj = derin.readObject(); 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException ioe) 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new InvalidKeySpecException(ioe.getMessage()); 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return obj; 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERObject toASN1Object() 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector spkac = new ASN1EncodableVector(); 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector pkac = new ASN1EncodableVector(); 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pkac.add(getKeySpec()); 281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam //ignore 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pkac.add(new DERIA5String(challenge)); 288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam spkac.add(new DERSequence(pkac)); 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam spkac.add(sigAlg); 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam spkac.add(new DERBitString(sigBits)); 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new DERSequence(spkac); 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 296