1 package org.cacert.gigi.crypto;
3 import java.io.IOException;
4 import java.security.GeneralSecurityException;
5 import java.security.Signature;
6 import java.security.SignatureException;
7 import sun.security.util.DerInputStream;
8 import sun.security.util.DerOutputStream;
9 import sun.security.util.DerValue;
10 import sun.security.x509.AlgorithmId;
11 import sun.security.x509.X509Key;
14 * This class handles a SPKAC. A SPKAC has the following structure;
17 * PublicKeyAndChallenge ::= SEQUENCE {
18 * spki SubjectPublicKeyInfo,
22 * SignedPublicKeyAndChallenge ::= SEQUENCE {
23 * publicKeyAndChallenge PublicKeyAndChallenge,
24 * signatureAlgorithm AlgorithmIdentifier,
25 * signature BIT STRING
31 private X509Key pubkey;
33 private String challenge;
35 public SPKAC(byte[] data) throws IOException, GeneralSecurityException {
36 DerInputStream derIn = new DerInputStream(data);
38 DerValue derSPKACContent[] = derIn.getSequence(3);
39 if (derIn.available() != 0) {
40 throw new IllegalArgumentException("Additional data after SPKAC.");
43 AlgorithmId id = AlgorithmId.parse(derSPKACContent[1]);
45 derIn = derSPKACContent[0].toDerInputStream();
47 pubkey = (X509Key) X509Key.parse(derIn.getDerValue());
49 DerValue derChallenge = derIn.getDerValue();
50 if (derIn.available() != 0) {
51 throw new IllegalArgumentException("Additional data after SPKAC.");
53 if (derChallenge.length() != 0) {
54 challenge = derChallenge.getIA5String();
57 Signature s = Signature.getInstance(id.getName());
59 s.update(derSPKACContent[0].toByteArray());
60 byte[] signature = derSPKACContent[2].getBitString();
61 if ( !s.verify(signature)) {
62 throw new SignatureException();
67 public String getChallenge() {
71 public X509Key getPubkey() {
75 public SPKAC(X509Key pubkey, String challange) {
77 challenge = challange;
80 public byte[] getEncoded(Signature sign) throws GeneralSecurityException, IOException {
81 DerOutputStream SPKAC = new DerOutputStream();
82 DerOutputStream SPKI = new DerOutputStream();
85 SPKI.putIA5String(challenge);
87 SPKAC.write(DerValue.tag_Sequence, SPKI);
88 byte[] toSign = SPKAC.toByteArray();
91 AlgorithmId aid = AlgorithmId.get(sign.getAlgorithm());
94 SPKAC.putBitString(sign.sign());
96 DerOutputStream res = new DerOutputStream();
97 res.write(DerValue.tag_Sequence, SPKAC);
99 byte[] result = res.toByteArray();