1 package org.bouncycastle.pqc.jcajce.provider.xmss;
2 
3 import java.io.IOException;
4 import java.security.InvalidKeyException;
5 import java.security.Key;
6 import java.security.KeyFactorySpi;
7 import java.security.PrivateKey;
8 import java.security.PublicKey;
9 import java.security.spec.InvalidKeySpecException;
10 import java.security.spec.KeySpec;
11 import java.security.spec.PKCS8EncodedKeySpec;
12 import java.security.spec.X509EncodedKeySpec;
13 
14 import org.bouncycastle.asn1.ASN1Primitive;
15 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
16 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
17 import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
18 
19 public class XMSSMTKeyFactorySpi
20     extends KeyFactorySpi
21     implements AsymmetricKeyInfoConverter
22 {
engineGeneratePrivate(KeySpec keySpec)23     public PrivateKey engineGeneratePrivate(KeySpec keySpec)
24         throws InvalidKeySpecException
25     {
26         if (keySpec instanceof PKCS8EncodedKeySpec)
27         {
28             // get the DER-encoded Key according to PKCS#8 from the spec
29             byte[] encKey = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
30 
31             try
32             {
33                 return generatePrivate(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey)));
34             }
35             catch (Exception e)
36             {
37                 throw new InvalidKeySpecException(e.toString());
38             }
39         }
40 
41         throw new InvalidKeySpecException("unsupported key specification: "
42             + keySpec.getClass() + ".");
43     }
44 
engineGeneratePublic(KeySpec keySpec)45     public PublicKey engineGeneratePublic(KeySpec keySpec)
46         throws InvalidKeySpecException
47     {
48         if (keySpec instanceof X509EncodedKeySpec)
49         {
50             // get the DER-encoded Key according to X.509 from the spec
51             byte[] encKey = ((X509EncodedKeySpec)keySpec).getEncoded();
52 
53             // decode the SubjectPublicKeyInfo data structure to the pki object
54             try
55             {
56                 return generatePublic(SubjectPublicKeyInfo.getInstance(encKey));
57             }
58             catch (Exception e)
59             {
60                 throw new InvalidKeySpecException(e.toString());
61             }
62         }
63 
64         throw new InvalidKeySpecException("unknown key specification: " + keySpec + ".");
65     }
66 
engineGetKeySpec(Key key, Class keySpec)67     public final KeySpec engineGetKeySpec(Key key, Class keySpec)
68         throws InvalidKeySpecException
69     {
70         if (key instanceof BCXMSSMTPrivateKey)
71         {
72             if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec))
73             {
74                 return new PKCS8EncodedKeySpec(key.getEncoded());
75             }
76         }
77         else if (key instanceof BCXMSSMTPublicKey)
78         {
79             if (X509EncodedKeySpec.class.isAssignableFrom(keySpec))
80             {
81                 return new X509EncodedKeySpec(key.getEncoded());
82             }
83         }
84         else
85         {
86             throw new InvalidKeySpecException("unsupported key type: "
87                 + key.getClass() + ".");
88         }
89 
90         throw new InvalidKeySpecException("unknown key specification: "
91             + keySpec + ".");
92     }
93 
engineTranslateKey(Key key)94     public final Key engineTranslateKey(Key key)
95         throws InvalidKeyException
96     {
97         if (key instanceof BCXMSSMTPrivateKey || key instanceof BCXMSSMTPublicKey)
98         {
99             return key;
100         }
101 
102         throw new InvalidKeyException("unsupported key type");
103     }
104 
generatePrivate(PrivateKeyInfo keyInfo)105     public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
106         throws IOException
107     {
108         return new BCXMSSMTPrivateKey(keyInfo);
109     }
110 
generatePublic(SubjectPublicKeyInfo keyInfo)111     public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
112         throws IOException
113     {
114         return new BCXMSSMTPublicKey(keyInfo);
115     }
116 }
117