~brian-thomason/+junk/bouncycastle

« back to all changes in this revision

Viewing changes to src/org/bouncycastle/cms/CMSEnvelopedGenerator.java

  • Committer: Brian Thomason
  • Date: 2011-12-20 17:20:32 UTC
  • Revision ID: brian.thomason@canonical.com-20111220172032-rdtm13jgdxtksacr
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.bouncycastle.cms;
 
2
 
 
3
import java.io.IOException;
 
4
import java.security.AlgorithmParameterGenerator;
 
5
import java.security.AlgorithmParameters;
 
6
import java.security.InvalidAlgorithmParameterException;
 
7
import java.security.InvalidKeyException;
 
8
import java.security.KeyPair;
 
9
import java.security.NoSuchAlgorithmException;
 
10
import java.security.NoSuchProviderException;
 
11
import java.security.PrivateKey;
 
12
import java.security.Provider;
 
13
import java.security.PublicKey;
 
14
import java.security.SecureRandom;
 
15
import java.security.cert.X509Certificate;
 
16
import java.util.ArrayList;
 
17
import java.util.Collection;
 
18
import java.util.Collections;
 
19
import java.util.List;
 
20
 
 
21
import javax.crypto.SecretKey;
 
22
import javax.crypto.spec.RC2ParameterSpec;
 
23
import javax.crypto.spec.SecretKeySpec;
 
24
 
 
25
import org.bouncycastle.asn1.ASN1Object;
 
26
import org.bouncycastle.asn1.DEREncodable;
 
27
import org.bouncycastle.asn1.DERNull;
 
28
import org.bouncycastle.asn1.DERObjectIdentifier;
 
29
import org.bouncycastle.asn1.DEROctetString;
 
30
import org.bouncycastle.asn1.cms.KEKIdentifier;
 
31
import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
 
32
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
 
33
import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
 
34
import org.bouncycastle.asn1.pkcs.PBKDF2Params;
 
35
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
 
36
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
 
37
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
 
38
 
 
39
/**
 
40
 * General class for generating a CMS enveloped-data message.
 
41
 */
 
42
public class CMSEnvelopedGenerator
 
43
{
 
44
    public static final String  DES_EDE3_CBC    = PKCSObjectIdentifiers.des_EDE3_CBC.getId();
 
45
    public static final String  RC2_CBC         = PKCSObjectIdentifiers.RC2_CBC.getId();
 
46
    public static final String  IDEA_CBC        = "1.3.6.1.4.1.188.7.1.1.2";
 
47
    public static final String  CAST5_CBC       = "1.2.840.113533.7.66.10";
 
48
    public static final String  AES128_CBC      = NISTObjectIdentifiers.id_aes128_CBC.getId();
 
49
    public static final String  AES192_CBC      = NISTObjectIdentifiers.id_aes192_CBC.getId();
 
50
    public static final String  AES256_CBC      = NISTObjectIdentifiers.id_aes256_CBC.getId();
 
51
    public static final String  CAMELLIA128_CBC = NTTObjectIdentifiers.id_camellia128_cbc.getId();
 
52
    public static final String  CAMELLIA192_CBC = NTTObjectIdentifiers.id_camellia192_cbc.getId();
 
53
    public static final String  CAMELLIA256_CBC = NTTObjectIdentifiers.id_camellia256_cbc.getId();
 
54
    public static final String  SEED_CBC        = KISAObjectIdentifiers.id_seedCBC.getId();
 
55
 
 
56
    public static final String  DES_EDE3_WRAP   = PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId();
 
57
    public static final String  AES128_WRAP     = NISTObjectIdentifiers.id_aes128_wrap.getId();
 
58
    public static final String  AES192_WRAP     = NISTObjectIdentifiers.id_aes192_wrap.getId();
 
59
    public static final String  AES256_WRAP     = NISTObjectIdentifiers.id_aes256_wrap.getId();
 
60
    public static final String  CAMELLIA128_WRAP = NTTObjectIdentifiers.id_camellia128_wrap.getId();
 
61
    public static final String  CAMELLIA192_WRAP = NTTObjectIdentifiers.id_camellia192_wrap.getId();
 
62
    public static final String  CAMELLIA256_WRAP = NTTObjectIdentifiers.id_camellia256_wrap.getId();
 
63
    public static final String  SEED_WRAP       = KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId();
 
64
 
 
65
    public static final String  ECDH_SHA1KDF    = X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme.getId();
 
66
    public static final String  ECMQV_SHA1KDF   = X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme.getId();
 
67
 
 
68
    final List oldRecipientInfoGenerators = new ArrayList();
 
69
    final List recipientInfoGenerators = new ArrayList();
 
70
 
 
71
    protected CMSAttributeTableGenerator unprotectedAttributeGenerator = null;
 
72
 
 
73
    final SecureRandom rand;
 
74
 
 
75
    /**
 
76
     * base constructor
 
77
     */
 
78
    public CMSEnvelopedGenerator()
 
79
    {
 
80
        this(new SecureRandom());
 
81
    }
 
82
 
 
83
    /**
 
84
     * constructor allowing specific source of randomness
 
85
     * @param rand instance of SecureRandom to use
 
86
     */
 
87
    public CMSEnvelopedGenerator(
 
88
        SecureRandom rand)
 
89
    {
 
90
        this.rand = rand;
 
91
    }
 
92
 
 
93
    public void setUnprotectedAttributeGenerator(CMSAttributeTableGenerator unprotectedAttributeGenerator)
 
94
    {
 
95
        this.unprotectedAttributeGenerator = unprotectedAttributeGenerator;
 
96
    }
 
97
 
 
98
    /**
 
99
     * add a recipient.
 
100
     *
 
101
     * @deprecated use the addRecipientGenerator and JceKeyTransRecipientInfoGenerator
 
102
     * @param cert recipient's public key certificate
 
103
     * @exception IllegalArgumentException if there is a problem with the certificate
 
104
     */
 
105
    public void addKeyTransRecipient(
 
106
        X509Certificate cert)
 
107
        throws IllegalArgumentException
 
108
    {
 
109
        KeyTransIntRecipientInfoGenerator ktrig = new KeyTransIntRecipientInfoGenerator();
 
110
        ktrig.setRecipientCert(cert);
 
111
 
 
112
        oldRecipientInfoGenerators.add(ktrig);
 
113
    }
 
114
 
 
115
    /**
 
116
     * add a recipient
 
117
     *
 
118
     * @deprecated use the addRecipientGenerator and JceKeyTransRecipientInfoGenerator
 
119
     * @param key the public key used by the recipient
 
120
     * @param subKeyId the identifier for the recipient's public key
 
121
     * @exception IllegalArgumentException if there is a problem with the key
 
122
     */
 
123
    public void addKeyTransRecipient(
 
124
        PublicKey   key,
 
125
        byte[]      subKeyId)
 
126
        throws IllegalArgumentException
 
127
    {
 
128
        KeyTransIntRecipientInfoGenerator ktrig = new KeyTransIntRecipientInfoGenerator();
 
129
        ktrig.setRecipientPublicKey(key);
 
130
        ktrig.setSubjectKeyIdentifier(new DEROctetString(subKeyId));
 
131
 
 
132
        oldRecipientInfoGenerators.add(ktrig);
 
133
    }
 
134
 
 
135
    /**
 
136
     * add a KEK recipient.
 
137
     *
 
138
     * @deprecated use the addRecipientGenerator and JceKEKRecipientInfoGenerator
 
139
     * @param key the secret key to use for wrapping
 
140
     * @param keyIdentifier the byte string that identifies the key
 
141
     */
 
142
    public void addKEKRecipient(
 
143
        SecretKey   key,
 
144
        byte[]      keyIdentifier)
 
145
    {
 
146
        addKEKRecipient(key, new KEKIdentifier(keyIdentifier, null, null));
 
147
    }
 
148
 
 
149
    /**
 
150
     * add a KEK recipient.
 
151
     *
 
152
     * @deprecated use the addRecipientGenerator and JceKEKRecipientInfoGenerator
 
153
     * @param key the secret key to use for wrapping
 
154
     * @param kekIdentifier a KEKIdentifier structure (identifies the key)
 
155
     */
 
156
    public void addKEKRecipient(
 
157
        SecretKey       key,
 
158
        KEKIdentifier   kekIdentifier)
 
159
    {
 
160
        KEKIntRecipientInfoGenerator kekrig = new KEKIntRecipientInfoGenerator();
 
161
        kekrig.setKEKIdentifier(kekIdentifier);
 
162
        kekrig.setKeyEncryptionKey(key);
 
163
 
 
164
        oldRecipientInfoGenerators.add(kekrig);
 
165
    }
 
166
 
 
167
    /**
 
168
     * @deprecated use addRecipientGenerator and JcePasswordRecipientInfoGenerator
 
169
     * @param pbeKey PBE key
 
170
     * @param kekAlgorithmOid key encryption algorithm to use.
 
171
     */
 
172
    public void addPasswordRecipient(
 
173
        CMSPBEKey pbeKey,
 
174
        String    kekAlgorithmOid)
 
175
    {
 
176
        PBKDF2Params params = new PBKDF2Params(pbeKey.getSalt(), pbeKey.getIterationCount());
 
177
 
 
178
        PasswordIntRecipientInfoGenerator prig = new PasswordIntRecipientInfoGenerator();
 
179
        prig.setKeyDerivationAlgorithm(new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBKDF2, params));
 
180
        prig.setKeyEncryptionKey(new SecretKeySpec(pbeKey.getEncoded(kekAlgorithmOid), kekAlgorithmOid));
 
181
 
 
182
        oldRecipientInfoGenerators.add(prig);
 
183
    }
 
184
 
 
185
    /**
 
186
     * Add a key agreement based recipient.
 
187
     *
 
188
     * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator
 
189
     * @param agreementAlgorithm key agreement algorithm to use.
 
190
     * @param senderPrivateKey private key to initialise sender side of agreement with.
 
191
     * @param senderPublicKey sender public key to include with message.
 
192
     * @param recipientCert recipient's public key certificate.
 
193
     * @param cekWrapAlgorithm OID for key wrapping algorithm to use.
 
194
     * @param provider provider to use for the agreement calculation.
 
195
     * @exception NoSuchProviderException if the specified provider cannot be found
 
196
     * @exception NoSuchAlgorithmException if the algorithm requested cannot be found
 
197
     * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified
 
198
     */
 
199
    public void addKeyAgreementRecipient(
 
200
        String           agreementAlgorithm,
 
201
        PrivateKey       senderPrivateKey,
 
202
        PublicKey        senderPublicKey,
 
203
        X509Certificate  recipientCert,
 
204
        String           cekWrapAlgorithm,
 
205
        String           provider)
 
206
        throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException
 
207
    {
 
208
        addKeyAgreementRecipient(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipientCert,  cekWrapAlgorithm, CMSUtils.getProvider(provider));
 
209
    }
 
210
 
 
211
    /**
 
212
     * Add a key agreement based recipient.
 
213
     *
 
214
     * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator
 
215
     * @param agreementAlgorithm key agreement algorithm to use.
 
216
     * @param senderPrivateKey private key to initialise sender side of agreement with.
 
217
     * @param senderPublicKey sender public key to include with message.
 
218
     * @param recipientCert recipient's public key certificate.
 
219
     * @param cekWrapAlgorithm OID for key wrapping algorithm to use.
 
220
     * @param provider provider to use for the agreement calculation.
 
221
     * @exception NoSuchAlgorithmException if the algorithm requested cannot be found
 
222
     * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified
 
223
     */
 
224
    public void addKeyAgreementRecipient(
 
225
        String           agreementAlgorithm,
 
226
        PrivateKey       senderPrivateKey,
 
227
        PublicKey        senderPublicKey,
 
228
        X509Certificate  recipientCert,
 
229
        String           cekWrapAlgorithm,
 
230
        Provider         provider)
 
231
        throws NoSuchAlgorithmException, InvalidKeyException
 
232
    {
 
233
        addKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey,
 
234
            Collections.singletonList(recipientCert), cekWrapAlgorithm, provider);
 
235
    }
 
236
 
 
237
    /**
 
238
     * Add multiple key agreement based recipients (sharing a single KeyAgreeRecipientInfo structure).
 
239
     *
 
240
     * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator
 
241
     * @param agreementAlgorithm key agreement algorithm to use.
 
242
     * @param senderPrivateKey private key to initialise sender side of agreement with.
 
243
     * @param senderPublicKey sender public key to include with message.
 
244
     * @param recipientCerts recipients' public key certificates.
 
245
     * @param cekWrapAlgorithm OID for key wrapping algorithm to use.
 
246
     * @param provider provider to use for the agreement calculation.
 
247
     * @exception NoSuchAlgorithmException if the algorithm requested cannot be found
 
248
     * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified
 
249
     */
 
250
    public void addKeyAgreementRecipients(
 
251
        String           agreementAlgorithm,
 
252
        PrivateKey       senderPrivateKey,
 
253
        PublicKey        senderPublicKey,
 
254
        Collection       recipientCerts,
 
255
        String           cekWrapAlgorithm,
 
256
        String           provider)
 
257
        throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException
 
258
    {
 
259
        addKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey, recipientCerts, cekWrapAlgorithm, CMSUtils.getProvider(provider));
 
260
    }
 
261
 
 
262
    /**
 
263
     * Add multiple key agreement based recipients (sharing a single KeyAgreeRecipientInfo structure).
 
264
     *
 
265
     * @deprecated use the addRecipientGenerator and JceKeyAgreeRecipientInfoGenerator
 
266
     * @param agreementAlgorithm key agreement algorithm to use.
 
267
     * @param senderPrivateKey private key to initialise sender side of agreement with.
 
268
     * @param senderPublicKey sender public key to include with message.
 
269
     * @param recipientCerts recipients' public key certificates.
 
270
     * @param cekWrapAlgorithm OID for key wrapping algorithm to use.
 
271
     * @param provider provider to use for the agreement calculation.
 
272
     * @exception NoSuchAlgorithmException if the algorithm requested cannot be found
 
273
     * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified
 
274
     */
 
275
    public void addKeyAgreementRecipients(
 
276
        String           agreementAlgorithm,
 
277
        PrivateKey       senderPrivateKey,
 
278
        PublicKey        senderPublicKey,
 
279
        Collection       recipientCerts,
 
280
        String           cekWrapAlgorithm,
 
281
        Provider         provider)
 
282
        throws NoSuchAlgorithmException, InvalidKeyException
 
283
    {
 
284
        /* TODO
 
285
         * "a recipient X.509 version 3 certificate that contains a key usage extension MUST
 
286
         * assert the keyAgreement bit."
 
287
         */
 
288
 
 
289
        KeyAgreeIntRecipientInfoGenerator karig = new KeyAgreeIntRecipientInfoGenerator();
 
290
        karig.setKeyAgreementOID(new DERObjectIdentifier(agreementAlgorithm));
 
291
        karig.setKeyEncryptionOID(new DERObjectIdentifier(cekWrapAlgorithm));
 
292
        karig.setRecipientCerts(recipientCerts);
 
293
        karig.setSenderKeyPair(new KeyPair(senderPublicKey, senderPrivateKey));
 
294
 
 
295
        oldRecipientInfoGenerators.add(karig);
 
296
    }
 
297
 
 
298
    /**
 
299
     * Add a generator to produce the recipient info required.
 
300
     * 
 
301
     * @param recipientGenerator a generator of a recipient info object.
 
302
     */
 
303
    public void addRecipientInfoGenerator(RecipientInfoGenerator recipientGenerator)
 
304
    {
 
305
        recipientInfoGenerators.add(recipientGenerator);
 
306
    }
 
307
 
 
308
    protected AlgorithmIdentifier getAlgorithmIdentifier(String encryptionOID, AlgorithmParameters params) throws IOException
 
309
    {
 
310
        DEREncodable asn1Params;
 
311
        if (params != null)
 
312
        {
 
313
            asn1Params = ASN1Object.fromByteArray(params.getEncoded("ASN.1"));
 
314
        }
 
315
        else
 
316
        {
 
317
            asn1Params = DERNull.INSTANCE;
 
318
        }
 
319
 
 
320
        return new AlgorithmIdentifier(
 
321
            new DERObjectIdentifier(encryptionOID),
 
322
            asn1Params);
 
323
    }
 
324
 
 
325
    protected AlgorithmParameters generateParameters(String encryptionOID, SecretKey encKey, Provider encProvider)
 
326
        throws CMSException
 
327
    {
 
328
        try
 
329
        {
 
330
            AlgorithmParameterGenerator pGen = AlgorithmParameterGenerator.getInstance(encryptionOID, encProvider);
 
331
 
 
332
            if (encryptionOID.equals(RC2_CBC))
 
333
            {
 
334
                byte[]  iv = new byte[8];
 
335
 
 
336
                rand.nextBytes(iv);
 
337
 
 
338
                try
 
339
                {
 
340
                    pGen.init(new RC2ParameterSpec(encKey.getEncoded().length * 8, iv), rand);
 
341
                }
 
342
                catch (InvalidAlgorithmParameterException e)
 
343
                {
 
344
                    throw new CMSException("parameters generation error: " + e, e);
 
345
                }
 
346
            }
 
347
 
 
348
            return pGen.generateParameters();
 
349
        }
 
350
        catch (NoSuchAlgorithmException e)
 
351
        {
 
352
            return null;
 
353
        }
 
354
    }
 
355
}