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