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