22
33import java .io .IOException ;
44import java .security .PrivateKey ;
5+ import java .security .Provider ;
6+ import java .security .Security ;
57import java .util .ArrayList ;
68import java .util .Collections ;
79import java .util .List ;
2931public class CompositePrivateKey
3032 implements PrivateKey
3133{
34+ public static class Builder
35+ {
36+ private final AlgorithmIdentifier algorithmIdentifier ;
37+ private final PrivateKey [] keys = new PrivateKey [2 ];
38+ private final Provider [] providers = new Provider [2 ];
39+
40+ private int count = 0 ;
41+
42+ private Builder (AlgorithmIdentifier algorithmIdentifier )
43+ {
44+ this .algorithmIdentifier = algorithmIdentifier ;
45+ }
46+
47+ public Builder addPrivateKey (PrivateKey key , String providerName )
48+ {
49+ return addPrivateKey (key , Security .getProvider (providerName ));
50+ }
51+
52+ public Builder addPrivateKey (PrivateKey key , Provider provider )
53+ {
54+ if (count == keys .length )
55+ {
56+ throw new IllegalStateException ("only " + keys .length + " allowed in composite" );
57+ }
58+
59+ keys [count ] = key ;
60+ providers [count ++] = provider ;
61+
62+ return this ;
63+ }
64+
65+ public CompositePrivateKey build ()
66+ {
67+ return new CompositePrivateKey (algorithmIdentifier , keys , providers );
68+ }
69+ }
70+
71+ public static Builder builder (ASN1ObjectIdentifier compAlgOid )
72+ {
73+ return new Builder (new AlgorithmIdentifier (compAlgOid ));
74+ }
75+
3276 private final List <PrivateKey > keys ;
77+ private final List <Provider > providers ;
3378
3479 private AlgorithmIdentifier algorithmIdentifier ;
3580
@@ -69,17 +114,44 @@ public CompositePrivateKey(AlgorithmIdentifier algorithmIdentifier, PrivateKey..
69114 List <PrivateKey > keyList = new ArrayList <PrivateKey >(keys .length );
70115 for (int i = 0 ; i < keys .length ; i ++)
71116 {
72- if (keys [i ] instanceof MLDSAPrivateKey )
73- {
74- // TODO: we don't insist on seed but we try to accommodate it - the debate continues
75- keyList .add (((MLDSAPrivateKey )keys [i ]).getPrivateKey (true ));
76- }
77- else
78- {
79- keyList .add (keys [i ]);
80- }
117+ keyList .add (processKey (keys [i ]));
81118 }
82119 this .keys = Collections .unmodifiableList (keyList );
120+ this .providers = null ;
121+ }
122+
123+ private PrivateKey processKey (PrivateKey key )
124+ {
125+ // we assume this also means BCKey
126+ if (key instanceof MLDSAPrivateKey )
127+ {
128+ // TODO: we don't insist on seed but we try to accommodate it - the debate continues
129+ return ((MLDSAPrivateKey )key ).getPrivateKey (true );
130+ }
131+ else
132+ {
133+ return key ;
134+ }
135+ }
136+
137+ private CompositePrivateKey (AlgorithmIdentifier algorithmIdentifier , PrivateKey [] keys , Provider [] providers )
138+ {
139+ this .algorithmIdentifier = algorithmIdentifier ;
140+
141+ if (keys .length != 2 )
142+ {
143+ throw new IllegalArgumentException ("two keys required for composite private key" );
144+ }
145+
146+ List <PrivateKey > keyList = new ArrayList <PrivateKey >(keys .length );
147+ List <Provider > providerList = new ArrayList <Provider >(providers .length );
148+ for (int i = 0 ; i < keys .length ; i ++)
149+ {
150+ providerList .add (providers [i ]);
151+ keyList .add (processKey (keys [i ]));
152+ }
153+ this .keys = Collections .unmodifiableList (keyList );
154+ this .providers = Collections .unmodifiableList (providerList );
83155 }
84156
85157 /**
@@ -111,6 +183,7 @@ public CompositePrivateKey(PrivateKeyInfo keyInfo)
111183 }
112184
113185 this .keys = privateKeyFromFactory .getPrivateKeys ();
186+ this .providers = null ;
114187 this .algorithmIdentifier = privateKeyFromFactory .getAlgorithmIdentifier ();
115188 }
116189
@@ -124,6 +197,16 @@ public List<PrivateKey> getPrivateKeys()
124197 return keys ;
125198 }
126199
200+ /**
201+ * Return a list of the providers supporting the component private keys.
202+ *
203+ * @return an immutable list of Provider objects.
204+ */
205+ public List <Provider > getProviders ()
206+ {
207+ return providers ;
208+ }
209+
127210 public String getAlgorithm ()
128211 {
129212 return CompositeIndex .getAlgorithmName (this .algorithmIdentifier .getAlgorithm ());
0 commit comments