Pkcs10CertificationRequestDelaySigned.cs
4.96 KB
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
using System;
using System.Collections;
using System.Globalization;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Pkcs
{
/// <remarks>
/// A class for creating and verifying Pkcs10 Certification requests (this is an extension on <see cref="Pkcs10CertificationRequest"/>).
/// The requests are made using delay signing. This is useful for situations where
/// the private key is in another environment and not directly accessible (e.g. HSM)
/// So the first step creates the request, then the signing is done outside this
/// object and the signature is then used to complete the request.
/// </remarks>
/// <code>
/// CertificationRequest ::= Sequence {
/// certificationRequestInfo CertificationRequestInfo,
/// signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
/// signature BIT STRING
/// }
///
/// CertificationRequestInfo ::= Sequence {
/// version Integer { v1(0) } (v1,...),
/// subject Name,
/// subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
/// attributes [0] Attributes{{ CRIAttributes }}
/// }
///
/// Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
///
/// Attr { ATTRIBUTE:IOSet } ::= Sequence {
/// type ATTRIBUTE.&id({IOSet}),
/// values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
/// }
/// </code>
/// see <a href="http://www.rsasecurity.com/rsalabs/node.asp?id=2132"/>
public class Pkcs10CertificationRequestDelaySigned : Pkcs10CertificationRequest
{
protected Pkcs10CertificationRequestDelaySigned()
: base()
{
}
public Pkcs10CertificationRequestDelaySigned(
byte[] encoded)
: base(encoded)
{
}
public Pkcs10CertificationRequestDelaySigned(
Asn1Sequence seq)
: base(seq)
{
}
public Pkcs10CertificationRequestDelaySigned(
Stream input)
: base(input)
{
}
public Pkcs10CertificationRequestDelaySigned(
string signatureAlgorithm,
X509Name subject,
AsymmetricKeyParameter publicKey,
Asn1Set attributes,
AsymmetricKeyParameter signingKey)
: base(signatureAlgorithm, subject, publicKey, attributes, signingKey)
{
}
/// <summary>
/// Instantiate a Pkcs10CertificationRequest object with the necessary credentials.
/// </summary>
/// <param name="signatureAlgorithm">Name of Sig Alg.</param>
/// <param name="subject">X509Name of subject eg OU="My unit." O="My Organisatioin" C="au" </param>
/// <param name="publicKey">Public Key to be included in cert reqest.</param>
/// <param name="attributes">ASN1Set of Attributes.</param>
/// <remarks>
/// After the object is constructed use the <see cref="GetDataToSign"/> and finally the
/// SignRequest methods to finalize the request.
/// </remarks>
public Pkcs10CertificationRequestDelaySigned(
string signatureAlgorithm,
X509Name subject,
AsymmetricKeyParameter publicKey,
Asn1Set attributes)
{
if (signatureAlgorithm == null)
throw new ArgumentNullException("signatureAlgorithm");
if (subject == null)
throw new ArgumentNullException("subject");
if (publicKey == null)
throw new ArgumentNullException("publicKey");
if (publicKey.IsPrivate)
throw new ArgumentException("expected public key", "publicKey");
// DerObjectIdentifier sigOid = SignerUtilities.GetObjectIdentifier(signatureAlgorithm);
string algorithmName = Platform.ToUpperInvariant(signatureAlgorithm);
DerObjectIdentifier sigOid = (DerObjectIdentifier) algorithms[algorithmName];
if (sigOid == null)
{
try
{
sigOid = new DerObjectIdentifier(algorithmName);
}
catch (Exception e)
{
throw new ArgumentException("Unknown signature type requested", e);
}
}
if (noParams.Contains(sigOid))
{
this.sigAlgId = new AlgorithmIdentifier(sigOid);
}
else if (exParams.Contains(algorithmName))
{
this.sigAlgId = new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]);
}
else
{
this.sigAlgId = new AlgorithmIdentifier(sigOid, DerNull.Instance);
}
SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
this.reqInfo = new CertificationRequestInfo(subject, pubInfo, attributes);
}
public byte[] GetDataToSign()
{
return reqInfo.GetDerEncoded();
}
public void SignRequest(byte[] signedData)
{
//build the signature from the signed data
sigBits = new DerBitString(signedData);
}
public void SignRequest(DerBitString signedData)
{
//build the signature from the signed data
sigBits = signedData;
}
}
}