1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Crmf;
using System.IO;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Crmf
{
public class EncryptedValueBuilder
{
private IKeyWrapper wrapper;
private ICipherBuilderWithKey encryptor;
private EncryptedValuePadder padder;
/**
* Create a builder that makes EncryptedValue structures.
*
* @param wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue.
* @param encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue.
*/
public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor) : this(wrapper, encryptor, null)
{
}
/**
* Create a builder that makes EncryptedValue structures with fixed length blocks padded using the passed in padder.
*
* @param wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue.
* @param encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue.
* @param padder a padder to ensure that the EncryptedValue created will always be a constant length.
*/
public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor, EncryptedValuePadder padder)
{
this.wrapper = wrapper;
this.encryptor = encryptor;
this.padder = padder;
}
/**
* Build an EncryptedValue structure containing the passed in pass phrase.
*
* @param revocationPassphrase a revocation pass phrase.
* @return an EncryptedValue containing the encrypted pass phrase.
* @throws CrmfException on a failure to encrypt the data, or wrap the symmetric key for this value.
*/
public EncryptedValue Build(char[] revocationPassphrase)
{
return encryptData(padData(Strings.ToUtf8ByteArray(revocationPassphrase)));
}
/**
* Build an EncryptedValue structure containing the certificate contained in
* the passed in holder.
*
* @param holder a holder containing a certificate.
* @return an EncryptedValue containing the encrypted certificate.
* @throws CrmfException on a failure to encrypt the data, or wrap the symmetric key for this value.
*/
public EncryptedValue Build(X509Certificate holder)
{
try
{
return encryptData(padData(holder.GetEncoded()));
}
catch (IOException e)
{
throw new CrmfException("cannot encode certificate: " + e.Message, e);
}
}
/**
* Build an EncryptedValue structure containing the private key contained in
* the passed info structure.
*
* @param privateKeyInfo a PKCS#8 private key info structure.
* @return an EncryptedValue containing an EncryptedPrivateKeyInfo structure.
* @throws CrmfException on a failure to encrypt the data, or wrap the symmetric key for this value.
*/
public EncryptedValue Build(PrivateKeyInfo privateKeyInfo)
{
Pkcs8EncryptedPrivateKeyInfoBuilder encInfoBldr = new Pkcs8EncryptedPrivateKeyInfoBuilder(privateKeyInfo);
AlgorithmIdentifier intendedAlg = privateKeyInfo.PrivateKeyAlgorithm;
AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails;
DerBitString encSymmKey;
try
{
Pkcs8EncryptedPrivateKeyInfo encInfo = encInfoBldr.Build(encryptor);
encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect());
AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails;
Asn1OctetString valueHint = null;
return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, new DerBitString(encInfo.GetEncryptedData()));
}
catch (Exception e)
{
throw new CrmfException("cannot wrap key: " + e.Message, e);
}
}
private EncryptedValue encryptData(byte[] data)
{
MemoryOutputStream bOut = new MemoryOutputStream();
Stream eOut = encryptor.BuildCipher(bOut).Stream;
try
{
eOut.Write(data, 0, data.Length);
eOut.Close();
}
catch (IOException e)
{
throw new CrmfException("cannot process data: " + e.Message, e);
}
AlgorithmIdentifier intendedAlg = null;
AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails;
DerBitString encSymmKey;
try
{
encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect());
}
catch (Exception e)
{
throw new CrmfException("cannot wrap key: " + e.Message, e);
}
AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails;
Asn1OctetString valueHint = null;
DerBitString encValue = new DerBitString(bOut.ToArray());
return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, encValue);
}
private byte[] padData(byte[] data)
{
if (padder != null)
{
return padder.GetPaddedData(data);
}
return data;
}
}
}
|