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

Save This Page
Home » crypto-143 » org.bouncycastle.jce.netscape » [javadoc | source]