1package org.bouncycastle.x509.extension;
2
3import java.io.IOException;
4import java.security.InvalidKeyException;
5import java.security.PublicKey;
6import java.security.cert.CertificateParsingException;
7import java.security.cert.X509Certificate;
8
9import org.bouncycastle.asn1.ASN1InputStream;
10import org.bouncycastle.asn1.ASN1OctetString;
11import org.bouncycastle.asn1.ASN1Sequence;
12import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
13import org.bouncycastle.asn1.x509.Extension;
14import org.bouncycastle.asn1.x509.GeneralName;
15import org.bouncycastle.asn1.x509.GeneralNames;
16import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
17import org.bouncycastle.asn1.x509.X509Extension;
18import org.bouncycastle.asn1.x509.X509Extensions;
19import org.bouncycastle.jce.PrincipalUtil;
20
21/**
22 * A high level authority key identifier.
23 * @deprecated use JcaX509ExtensionUtils and AuthorityKeyIdentifier.getInstance()
24 */
25public class AuthorityKeyIdentifierStructure
26    extends AuthorityKeyIdentifier
27{
28    /**
29     * Constructor which will take the byte[] returned from getExtensionValue()
30     *
31     * @param encodedValue a DER octet encoded string with the extension structure in it.
32     * @throws IOException on parsing errors.
33     */
34    public AuthorityKeyIdentifierStructure(
35        byte[]  encodedValue)
36        throws IOException
37    {
38        super((ASN1Sequence)X509ExtensionUtil.fromExtensionValue(encodedValue));
39    }
40
41    /**
42     * Constructor which will take an extension
43     *
44     * @param extension a X509Extension object containing an AuthorityKeyIdentifier.
45     * @deprecated use constructor that takes Extension
46     */
47    public AuthorityKeyIdentifierStructure(
48        X509Extension extension)
49    {
50        super((ASN1Sequence)extension.getParsedValue());
51    }
52
53    /**
54     * Constructor which will take an extension
55     *
56     * @param extension a X509Extension object containing an AuthorityKeyIdentifier.
57     */
58    public AuthorityKeyIdentifierStructure(
59        Extension extension)
60    {
61        super((ASN1Sequence)extension.getParsedValue());
62    }
63
64    private static ASN1Sequence fromCertificate(
65        X509Certificate certificate)
66        throws CertificateParsingException
67    {
68        try
69        {
70            if (certificate.getVersion() != 3)
71            {
72                GeneralName          genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate));
73                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
74                        (ASN1Sequence)new ASN1InputStream(certificate.getPublicKey().getEncoded()).readObject());
75
76                return (ASN1Sequence)new AuthorityKeyIdentifier(
77                               info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object();
78            }
79            else
80            {
81                GeneralName             genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate));
82
83                byte[]                  ext = certificate.getExtensionValue(X509Extensions.SubjectKeyIdentifier.getId());
84
85                if (ext != null)
86                {
87                    ASN1OctetString     str = (ASN1OctetString)X509ExtensionUtil.fromExtensionValue(ext);
88
89                    return (ASN1Sequence)new AuthorityKeyIdentifier(
90                                    str.getOctets(), new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object();
91                }
92                else
93                {
94                    SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
95                            (ASN1Sequence)new ASN1InputStream(certificate.getPublicKey().getEncoded()).readObject());
96
97                    return (ASN1Sequence)new AuthorityKeyIdentifier(
98                            info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object();
99                }
100            }
101        }
102        catch (Exception e)
103        {
104            throw new CertificateParsingException("Exception extracting certificate details: " + e.toString());
105        }
106    }
107
108    private static ASN1Sequence fromKey(
109        PublicKey pubKey)
110        throws InvalidKeyException
111    {
112        try
113        {
114            SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
115                                        (ASN1Sequence)new ASN1InputStream(pubKey.getEncoded()).readObject());
116
117            return (ASN1Sequence)new AuthorityKeyIdentifier(info).toASN1Object();
118        }
119        catch (Exception e)
120        {
121            throw new InvalidKeyException("can't process key: " + e);
122        }
123    }
124
125    /**
126     * Create an AuthorityKeyIdentifier using the passed in certificate's public
127     * key, issuer and serial number.
128     *
129     * @param certificate the certificate providing the information.
130     * @throws CertificateParsingException if there is a problem processing the certificate
131     */
132    public AuthorityKeyIdentifierStructure(
133        X509Certificate certificate)
134        throws CertificateParsingException
135    {
136        super(fromCertificate(certificate));
137    }
138
139    /**
140     * Create an AuthorityKeyIdentifier using just the hash of the
141     * public key.
142     *
143     * @param pubKey the key to generate the hash from.
144     * @throws InvalidKeyException if there is a problem using the key.
145     */
146    public AuthorityKeyIdentifierStructure(
147        PublicKey pubKey)
148        throws InvalidKeyException
149    {
150        super(fromKey(pubKey));
151    }
152}
153