1 package club.wpia.gigi.crypto;
3 import java.io.IOException;
4 import java.security.GeneralSecurityException;
5 import java.security.Signature;
6 import java.security.SignatureException;
8 import sun.security.util.DerInputStream;
9 import sun.security.util.DerOutputStream;
10 import sun.security.util.DerValue;
11 import sun.security.x509.AlgorithmId;
12 import sun.security.x509.X509Key;
15 * This class handles a SPKAC. A SPKAC has the following structure;
18 * PublicKeyAndChallenge ::= SEQUENCE {
19 * spki SubjectPublicKeyInfo,
23 * SignedPublicKeyAndChallenge ::= SEQUENCE {
24 * publicKeyAndChallenge PublicKeyAndChallenge,
25 * signatureAlgorithm AlgorithmIdentifier,
26 * signature BIT STRING
32 private X509Key pubkey;
34 private String challenge;
36 public SPKAC(byte[] data) throws IOException, GeneralSecurityException {
37 DerInputStream derIn = new DerInputStream(data);
39 DerValue derSPKACContent[] = derIn.getSequence(3);
40 if (derIn.available() != 0) {
41 throw new IllegalArgumentException("Additional data after SPKAC.");
44 AlgorithmId id = AlgorithmId.parse(derSPKACContent[1]);
46 derIn = derSPKACContent[0].toDerInputStream();
48 pubkey = (X509Key) X509Key.parse(derIn.getDerValue());
50 DerValue derChallenge = derIn.getDerValue();
51 if (derIn.available() != 0) {
52 throw new IllegalArgumentException("Additional data after SPKAC.");
54 if (derChallenge.length() != 0) {
55 challenge = derChallenge.getIA5String();
58 Signature s = Signature.getInstance(id.getName());
60 s.update(derSPKACContent[0].toByteArray());
61 byte[] signature = derSPKACContent[2].getBitString();
62 if ( !s.verify(signature)) {
63 throw new SignatureException();
68 public String getChallenge() {
72 public X509Key getPubkey() {
76 public SPKAC(X509Key pubkey, String challenge) {
78 this.challenge = challenge;
81 public byte[] getEncoded(Signature sign) throws GeneralSecurityException, IOException {
82 DerOutputStream SPKAC = new DerOutputStream();
83 DerOutputStream SPKI = new DerOutputStream();
86 SPKI.putIA5String(challenge);
88 SPKAC.write(DerValue.tag_Sequence, SPKI);
89 byte[] toSign = SPKAC.toByteArray();
92 AlgorithmId aid = AlgorithmId.get(sign.getAlgorithm());
95 SPKAC.putBitString(sign.sign());
97 DerOutputStream res = new DerOutputStream();
98 res.write(DerValue.tag_Sequence, SPKAC);
100 byte[] result = res.toByteArray();