1package org.bouncycastle.jcajce.provider.asymmetric.dh;
2
3import java.io.IOException;
4import java.security.InvalidKeyException;
5import java.security.Key;
6import java.security.PrivateKey;
7import java.security.PublicKey;
8import java.security.spec.InvalidKeySpecException;
9import java.security.spec.KeySpec;
10
11import javax.crypto.interfaces.DHPrivateKey;
12import javax.crypto.interfaces.DHPublicKey;
13import javax.crypto.spec.DHPrivateKeySpec;
14import javax.crypto.spec.DHPublicKeySpec;
15
16import org.bouncycastle.asn1.ASN1ObjectIdentifier;
17import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
18import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
19import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
20import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
21import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
22
23public class KeyFactorySpi
24    extends BaseKeyFactorySpi
25{
26    public KeyFactorySpi()
27    {
28    }
29
30    protected KeySpec engineGetKeySpec(
31        Key key,
32        Class spec)
33        throws InvalidKeySpecException
34    {
35        if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey)
36        {
37            DHPrivateKey k = (DHPrivateKey)key;
38
39            return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG());
40        }
41        else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey)
42        {
43            DHPublicKey k = (DHPublicKey)key;
44
45            return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG());
46        }
47
48        return super.engineGetKeySpec(key, spec);
49    }
50
51    protected Key engineTranslateKey(
52        Key key)
53        throws InvalidKeyException
54    {
55        if (key instanceof DHPublicKey)
56        {
57            return new BCDHPublicKey((DHPublicKey)key);
58        }
59        else if (key instanceof DHPrivateKey)
60        {
61            return new BCDHPrivateKey((DHPrivateKey)key);
62        }
63
64        throw new InvalidKeyException("key type unknown");
65    }
66
67    protected PrivateKey engineGeneratePrivate(
68        KeySpec keySpec)
69        throws InvalidKeySpecException
70    {
71        if (keySpec instanceof DHPrivateKeySpec)
72        {
73            return new BCDHPrivateKey((DHPrivateKeySpec)keySpec);
74        }
75
76        return super.engineGeneratePrivate(keySpec);
77    }
78
79    protected PublicKey engineGeneratePublic(
80        KeySpec keySpec)
81        throws InvalidKeySpecException
82    {
83        if (keySpec instanceof DHPublicKeySpec)
84        {
85            return new BCDHPublicKey((DHPublicKeySpec)keySpec);
86        }
87
88        return super.engineGeneratePublic(keySpec);
89    }
90
91    public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
92        throws IOException
93    {
94        ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm();
95
96        if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement))
97        {
98            return new BCDHPrivateKey(keyInfo);
99        }
100        else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber))
101        {
102            return new BCDHPrivateKey(keyInfo);
103        }
104        else
105        {
106            throw new IOException("algorithm identifier " + algOid + " in key not recognised");
107        }
108    }
109
110    public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
111        throws IOException
112    {
113        ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm();
114
115        if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement))
116        {
117            return new BCDHPublicKey(keyInfo);
118        }
119        else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber))
120        {
121            return new BCDHPublicKey(keyInfo);
122        }
123        else
124        {
125            throw new IOException("algorithm identifier " + algOid + " in key not recognised");
126        }
127    }
128}
129