1 /* $OpenBSD: rsa_asn1.c,v 1.13 2016/12/30 15:47:07 jsing Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 #include <stdio.h>
60 
61 #include <openssl/asn1t.h>
62 #include <openssl/bn.h>
63 #include <openssl/rsa.h>
64 #include <openssl/x509.h>
65 
66 /* Override the default free and new methods */
67 static int
68 rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
69 {
70 	if (operation == ASN1_OP_NEW_PRE) {
71 		*pval = (ASN1_VALUE *)RSA_new();
72 		if (*pval)
73 			return 2;
74 		return 0;
75 	} else if (operation == ASN1_OP_FREE_PRE) {
76 		RSA_free((RSA *)*pval);
77 		*pval = NULL;
78 		return 2;
79 	}
80 	return 1;
81 }
82 
83 static const ASN1_AUX RSAPrivateKey_aux = {
84 	.app_data = NULL,
85 	.flags = 0,
86 	.ref_offset = 0,
87 	.ref_lock = 0,
88 	.asn1_cb = rsa_cb,
89 	.enc_offset = 0,
90 };
91 static const ASN1_TEMPLATE RSAPrivateKey_seq_tt[] = {
92 	{
93 		.flags = 0,
94 		.tag = 0,
95 		.offset = offsetof(RSA, version),
96 		.field_name = "version",
97 		.item = &LONG_it,
98 	},
99 	{
100 		.flags = 0,
101 		.tag = 0,
102 		.offset = offsetof(RSA, n),
103 		.field_name = "n",
104 		.item = &BIGNUM_it,
105 	},
106 	{
107 		.flags = 0,
108 		.tag = 0,
109 		.offset = offsetof(RSA, e),
110 		.field_name = "e",
111 		.item = &BIGNUM_it,
112 	},
113 	{
114 		.flags = 0,
115 		.tag = 0,
116 		.offset = offsetof(RSA, d),
117 		.field_name = "d",
118 		.item = &BIGNUM_it,
119 	},
120 	{
121 		.flags = 0,
122 		.tag = 0,
123 		.offset = offsetof(RSA, p),
124 		.field_name = "p",
125 		.item = &BIGNUM_it,
126 	},
127 	{
128 		.flags = 0,
129 		.tag = 0,
130 		.offset = offsetof(RSA, q),
131 		.field_name = "q",
132 		.item = &BIGNUM_it,
133 	},
134 	{
135 		.flags = 0,
136 		.tag = 0,
137 		.offset = offsetof(RSA, dmp1),
138 		.field_name = "dmp1",
139 		.item = &BIGNUM_it,
140 	},
141 	{
142 		.flags = 0,
143 		.tag = 0,
144 		.offset = offsetof(RSA, dmq1),
145 		.field_name = "dmq1",
146 		.item = &BIGNUM_it,
147 	},
148 	{
149 		.flags = 0,
150 		.tag = 0,
151 		.offset = offsetof(RSA, iqmp),
152 		.field_name = "iqmp",
153 		.item = &BIGNUM_it,
154 	},
155 };
156 
157 const ASN1_ITEM RSAPrivateKey_it = {
158 	.itype = ASN1_ITYPE_SEQUENCE,
159 	.utype = V_ASN1_SEQUENCE,
160 	.templates = RSAPrivateKey_seq_tt,
161 	.tcount = sizeof(RSAPrivateKey_seq_tt) / sizeof(ASN1_TEMPLATE),
162 	.funcs = &RSAPrivateKey_aux,
163 	.size = sizeof(RSA),
164 	.sname = "RSA",
165 };
166 
167 
168 static const ASN1_AUX RSAPublicKey_aux = {
169 	.app_data = NULL,
170 	.flags = 0,
171 	.ref_offset = 0,
172 	.ref_lock = 0,
173 	.asn1_cb = rsa_cb,
174 	.enc_offset = 0,
175 };
176 static const ASN1_TEMPLATE RSAPublicKey_seq_tt[] = {
177 	{
178 		.flags = 0,
179 		.tag = 0,
180 		.offset = offsetof(RSA, n),
181 		.field_name = "n",
182 		.item = &BIGNUM_it,
183 	},
184 	{
185 		.flags = 0,
186 		.tag = 0,
187 		.offset = offsetof(RSA, e),
188 		.field_name = "e",
189 		.item = &BIGNUM_it,
190 	},
191 };
192 
193 const ASN1_ITEM RSAPublicKey_it = {
194 	.itype = ASN1_ITYPE_SEQUENCE,
195 	.utype = V_ASN1_SEQUENCE,
196 	.templates = RSAPublicKey_seq_tt,
197 	.tcount = sizeof(RSAPublicKey_seq_tt) / sizeof(ASN1_TEMPLATE),
198 	.funcs = &RSAPublicKey_aux,
199 	.size = sizeof(RSA),
200 	.sname = "RSA",
201 };
202 
203 static const ASN1_TEMPLATE RSA_PSS_PARAMS_seq_tt[] = {
204 	{
205 		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
206 		.tag = 0,
207 		.offset = offsetof(RSA_PSS_PARAMS, hashAlgorithm),
208 		.field_name = "hashAlgorithm",
209 		.item = &X509_ALGOR_it,
210 	},
211 	{
212 		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
213 		.tag = 1,
214 		.offset = offsetof(RSA_PSS_PARAMS, maskGenAlgorithm),
215 		.field_name = "maskGenAlgorithm",
216 		.item = &X509_ALGOR_it,
217 	},
218 	{
219 		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
220 		.tag = 2,
221 		.offset = offsetof(RSA_PSS_PARAMS, saltLength),
222 		.field_name = "saltLength",
223 		.item = &ASN1_INTEGER_it,
224 	},
225 	{
226 		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
227 		.tag = 3,
228 		.offset = offsetof(RSA_PSS_PARAMS, trailerField),
229 		.field_name = "trailerField",
230 		.item = &ASN1_INTEGER_it,
231 	},
232 };
233 
234 const ASN1_ITEM RSA_PSS_PARAMS_it = {
235 	.itype = ASN1_ITYPE_SEQUENCE,
236 	.utype = V_ASN1_SEQUENCE,
237 	.templates = RSA_PSS_PARAMS_seq_tt,
238 	.tcount = sizeof(RSA_PSS_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE),
239 	.funcs = NULL,
240 	.size = sizeof(RSA_PSS_PARAMS),
241 	.sname = "RSA_PSS_PARAMS",
242 };
243 
244 
245 RSA_PSS_PARAMS *
246 d2i_RSA_PSS_PARAMS(RSA_PSS_PARAMS **a, const unsigned char **in, long len)
247 {
248 	return (RSA_PSS_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
249 	    &RSA_PSS_PARAMS_it);
250 }
251 
252 int
253 i2d_RSA_PSS_PARAMS(RSA_PSS_PARAMS *a, unsigned char **out)
254 {
255 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSA_PSS_PARAMS_it);
256 }
257 
258 RSA_PSS_PARAMS *
259 RSA_PSS_PARAMS_new(void)
260 {
261 	return (RSA_PSS_PARAMS *)ASN1_item_new(&RSA_PSS_PARAMS_it);
262 }
263 
264 void
265 RSA_PSS_PARAMS_free(RSA_PSS_PARAMS *a)
266 {
267 	ASN1_item_free((ASN1_VALUE *)a, &RSA_PSS_PARAMS_it);
268 }
269 
270 
271 RSA *
272 d2i_RSAPrivateKey(RSA **a, const unsigned char **in, long len)
273 {
274 	return (RSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
275 	    &RSAPrivateKey_it);
276 }
277 
278 int
279 i2d_RSAPrivateKey(const RSA *a, unsigned char **out)
280 {
281 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSAPrivateKey_it);
282 }
283 
284 
285 RSA *
286 d2i_RSAPublicKey(RSA **a, const unsigned char **in, long len)
287 {
288 	return (RSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
289 	    &RSAPublicKey_it);
290 }
291 
292 int
293 i2d_RSAPublicKey(const RSA *a, unsigned char **out)
294 {
295 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSAPublicKey_it);
296 }
297 
298 RSA *
299 RSAPublicKey_dup(RSA *rsa)
300 {
301 	return ASN1_item_dup(&RSAPublicKey_it, rsa);
302 }
303 
304 RSA *
305 RSAPrivateKey_dup(RSA *rsa)
306 {
307 	return ASN1_item_dup(&RSAPrivateKey_it, rsa);
308 }
309