summary refs log tree commit diff
path: root/crypto/src/pkcs/Pkcs10CertificationRequestDelaySigned.cs
blob: e3a710f37a8f4f589c9e91fe2fda0c4634d0f454 (plain) (blame)
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
using System;
using System.IO;

using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
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.&amp;id({IOSet}),
	///    values  Set SIZE(1..MAX) OF ATTRIBUTE.&amp;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 = CollectionUtilities.GetValueOrNull(m_algorithms, signatureAlgorithm);
			if (sigOid == null)
			{
				try
				{
					sigOid = new DerObjectIdentifier(signatureAlgorithm);
				}
				catch (Exception e)
				{
					throw new ArgumentException("Unknown signature type requested", e);
				}
			}
			if (m_noParams.Contains(sigOid))
			{
				this.sigAlgId = new AlgorithmIdentifier(sigOid);
			}
			else if (m_exParams.TryGetValue(signatureAlgorithm, out var explicitParameters))
			{
				this.sigAlgId = new AlgorithmIdentifier(sigOid, explicitParameters);
			}
			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;
		}
	}
}