1 /* $NetBSD: req.c,v 1.1.1.1 2011/04/13 18:15:12 elric Exp $ */
4 * Copyright (c) 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <krb5/pkcs10_asn1.h>
39 struct hx509_request_data
{
41 SubjectPublicKeyInfo key
;
51 hx509_request_init(hx509_context context
, hx509_request
*req
)
53 *req
= calloc(1, sizeof(**req
));
61 hx509_request_free(hx509_request
*req
)
64 hx509_name_free(&(*req
)->name
);
65 free_SubjectPublicKeyInfo(&(*req
)->key
);
66 free_ExtKeyUsage(&(*req
)->eku
);
67 free_GeneralNames(&(*req
)->san
);
68 memset(*req
, 0, sizeof(**req
));
74 hx509_request_set_name(hx509_context context
,
79 hx509_name_free(&req
->name
);
81 int ret
= hx509_name_copy(context
, name
, &req
->name
);
89 hx509_request_get_name(hx509_context context
,
93 if (req
->name
== NULL
) {
94 hx509_set_error_string(context
, 0, EINVAL
, "Request have no name");
97 return hx509_name_copy(context
, req
->name
, name
);
101 hx509_request_set_SubjectPublicKeyInfo(hx509_context context
,
103 const SubjectPublicKeyInfo
*key
)
105 free_SubjectPublicKeyInfo(&req
->key
);
106 return copy_SubjectPublicKeyInfo(key
, &req
->key
);
110 hx509_request_get_SubjectPublicKeyInfo(hx509_context context
,
112 SubjectPublicKeyInfo
*key
)
114 return copy_SubjectPublicKeyInfo(&req
->key
, key
);
118 _hx509_request_add_eku(hx509_context context
,
125 val
= realloc(req
->eku
.val
, sizeof(req
->eku
.val
[0]) * (req
->eku
.len
+ 1));
130 ret
= der_copy_oid(oid
, &req
->eku
.val
[req
->eku
.len
]);
140 _hx509_request_add_dns_name(hx509_context context
,
142 const char *hostname
)
146 memset(&name
, 0, sizeof(name
));
147 name
.element
= choice_GeneralName_dNSName
;
148 name
.u
.dNSName
.data
= rk_UNCONST(hostname
);
149 name
.u
.dNSName
.length
= strlen(hostname
);
151 return add_GeneralNames(&req
->san
, &name
);
155 _hx509_request_add_email(hx509_context context
,
161 memset(&name
, 0, sizeof(name
));
162 name
.element
= choice_GeneralName_rfc822Name
;
163 name
.u
.dNSName
.data
= rk_UNCONST(email
);
164 name
.u
.dNSName
.length
= strlen(email
);
166 return add_GeneralNames(&req
->san
, &name
);
172 _hx509_request_to_pkcs10(hx509_context context
,
173 const hx509_request req
,
174 const hx509_private_key signer
,
175 heim_octet_string
*request
)
177 CertificationRequest r
;
178 heim_octet_string data
, os
;
182 if (req
->name
== NULL
) {
183 hx509_set_error_string(context
, 0, EINVAL
,
184 "PKCS10 needs to have a subject");
188 memset(&r
, 0, sizeof(r
));
189 memset(request
, 0, sizeof(*request
));
191 r
.certificationRequestInfo
.version
= pkcs10_v1
;
193 ret
= copy_Name(&req
->name
->der_name
,
194 &r
.certificationRequestInfo
.subject
);
197 ret
= copy_SubjectPublicKeyInfo(&req
->key
,
198 &r
.certificationRequestInfo
.subjectPKInfo
);
201 r
.certificationRequestInfo
.attributes
=
202 calloc(1, sizeof(*r
.certificationRequestInfo
.attributes
));
203 if (r
.certificationRequestInfo
.attributes
== NULL
) {
208 ASN1_MALLOC_ENCODE(CertificationRequestInfo
, data
.data
, data
.length
,
209 &r
.certificationRequestInfo
, &size
, ret
);
212 if (data
.length
!= size
)
215 ret
= _hx509_create_signature(context
,
217 _hx509_crypto_default_sig_alg
,
219 &r
.signatureAlgorithm
,
224 r
.signature
.data
= os
.data
;
225 r
.signature
.length
= os
.length
* 8;
227 ASN1_MALLOC_ENCODE(CertificationRequest
, data
.data
, data
.length
,
231 if (data
.length
!= size
)
237 free_CertificationRequest(&r
);
243 _hx509_request_parse(hx509_context context
,
247 CertificationRequest r
;
248 CertificationRequestInfo
*rinfo
;
254 if (strncmp(path
, "PKCS10:", 7) != 0) {
255 hx509_set_error_string(context
, 0, HX509_UNSUPPORTED_OPERATION
,
256 "unsupport type in %s", path
);
257 return HX509_UNSUPPORTED_OPERATION
;
261 /* XXX PEM request */
263 ret
= rk_undumpdata(path
, &p
, &len
);
265 hx509_set_error_string(context
, 0, ret
, "Failed to map file %s", path
);
269 ret
= decode_CertificationRequest(p
, len
, &r
, &size
);
272 hx509_set_error_string(context
, 0, ret
, "Failed to decode %s", path
);
276 ret
= hx509_request_init(context
, req
);
278 free_CertificationRequest(&r
);
282 rinfo
= &r
.certificationRequestInfo
;
284 ret
= hx509_request_set_SubjectPublicKeyInfo(context
, *req
,
285 &rinfo
->subjectPKInfo
);
287 free_CertificationRequest(&r
);
288 hx509_request_free(req
);
292 ret
= _hx509_name_from_Name(&rinfo
->subject
, &subject
);
294 free_CertificationRequest(&r
);
295 hx509_request_free(req
);
298 ret
= hx509_request_set_name(context
, *req
, subject
);
299 hx509_name_free(&subject
);
300 free_CertificationRequest(&r
);
302 hx509_request_free(req
);
311 _hx509_request_print(hx509_context context
, hx509_request req
, FILE *f
)
317 ret
= hx509_name_to_string(req
->name
, &subject
);
319 hx509_set_error_string(context
, 0, ret
, "Failed to print name");
322 fprintf(f
, "name: %s\n", subject
);