xref: /illumos-gate/usr/src/lib/libkmf/libkmf/common/csrcrlop.c (revision 150d2c5288c645a1c1a7d2bee61199a3729406c7)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <stdio.h>
29 #include <link.h>
30 #include <fcntl.h>
31 #include <ctype.h>
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/socket.h>
36 
37 #include <ber_der.h>
38 #include <kmfapiP.h>
39 
40 #include <pem_encode.h>
41 #include <libgen.h>
42 #include <cryptoutil.h>
43 
44 
45 /*
46  *
47  * Name: KMF_SetCSRPubKey
48  *
49  * Description:
50  *   This function converts the specified plugin public key to SPKI form,
51  *   and save it in the KMF_CSR_DATA internal structure
52  *
53  * Parameters:
54  *   KMFkey(input) - pointer to the KMF_KEY_HANDLE structure containing the
55  *		public key generated by the plug-in CreateKeypair
56  *   Csr(input/output) - pointer to a KMF_CSR_DATA structure containing
57  *		SPKI
58  *
59  * Returns:
60  *   A KMF_RETURN value indicating success or specifying a particular
61  *   error condition.
62  *   The value KMF_OK indicates success. All other values represent
63  *   an error condition.
64  *
65  */
66 KMF_RETURN
67 KMF_SetCSRPubKey(KMF_HANDLE_T handle,
68 	KMF_KEY_HANDLE *KMFKey,
69 	KMF_CSR_DATA *Csr)
70 {
71 	KMF_RETURN ret = KMF_OK;
72 	KMF_X509_SPKI *spki_ptr;
73 	KMF_PLUGIN *plugin;
74 	KMF_DATA KeyData = {NULL, 0};
75 
76 	CLEAR_ERROR(handle, ret);
77 	if (ret != KMF_OK)
78 		return (ret);
79 
80 	if (KMFKey == NULL || Csr == NULL) {
81 		return (KMF_ERR_BAD_PARAMETER);
82 	}
83 
84 	/* The keystore must extract the pubkey data */
85 	plugin = FindPlugin(handle, KMFKey->kstype);
86 	if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) {
87 		ret = plugin->funclist->EncodePubkeyData(handle,
88 		    KMFKey, &KeyData);
89 	} else {
90 		return (KMF_ERR_PLUGIN_NOTFOUND);
91 	}
92 
93 	spki_ptr = &Csr->csr.subjectPublicKeyInfo;
94 
95 	ret = DerDecodeSPKI(&KeyData, spki_ptr);
96 
97 	KMF_FreeData(&KeyData);
98 
99 	return (ret);
100 }
101 
102 KMF_RETURN
103 KMF_SetCSRVersion(KMF_CSR_DATA *CsrData, uint32_t version)
104 {
105 	if (CsrData == NULL)
106 		return (KMF_ERR_BAD_PARAMETER);
107 
108 	/*
109 	 * From RFC 3280:
110 	 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
111 	 */
112 	if (version != 0 && version != 1 && version != 2)
113 		return (KMF_ERR_BAD_PARAMETER);
114 	return (set_integer(&CsrData->csr.version, (void *)&version,
115 		sizeof (uint32_t)));
116 }
117 
118 KMF_RETURN
119 KMF_SetCSRSubjectName(KMF_CSR_DATA *CsrData,
120 	KMF_X509_NAME *subject_name_ptr)
121 {
122 	if (CsrData != NULL && subject_name_ptr != NULL)
123 		CsrData->csr.subject = *subject_name_ptr;
124 	else
125 		return (KMF_ERR_BAD_PARAMETER);
126 
127 	return (KMF_OK);
128 }
129 
130 KMF_RETURN
131 KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format,
132 	char *csrfile)
133 {
134 	KMF_RETURN rv = KMF_OK;
135 	int fd = -1;
136 	KMF_DATA pemdata = {NULL, 0};
137 
138 	if (csrdata == NULL || csrfile == NULL)
139 		return (KMF_ERR_BAD_PARAMETER);
140 
141 	if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
142 		return (KMF_ERR_BAD_PARAMETER);
143 
144 	if (format == KMF_FORMAT_PEM) {
145 		int len;
146 		rv = KMF_Der2Pem(KMF_CSR,
147 			csrdata->Data, csrdata->Length,
148 			&pemdata.Data, &len);
149 		if (rv != KMF_OK)
150 			goto cleanup;
151 		pemdata.Length = (size_t)len;
152 	}
153 
154 	if ((fd = open(csrfile, O_CREAT |O_RDWR, 0644)) == -1) {
155 		rv = KMF_ERR_OPEN_FILE;
156 		goto cleanup;
157 	}
158 
159 	if (format == KMF_FORMAT_PEM) {
160 		if (write(fd, pemdata.Data, pemdata.Length) !=
161 			pemdata.Length) {
162 			rv = KMF_ERR_WRITE_FILE;
163 		}
164 	} else {
165 		if (write(fd, csrdata->Data, csrdata->Length) !=
166 			csrdata->Length) {
167 			rv = KMF_ERR_WRITE_FILE;
168 		}
169 	}
170 
171 cleanup:
172 	if (fd != -1)
173 		(void) close(fd);
174 
175 	KMF_FreeData(&pemdata);
176 
177 	return (rv);
178 }
179 
180 KMF_RETURN
181 KMF_SetCSRExtension(KMF_CSR_DATA *Csr,
182 	KMF_X509_EXTENSION *extn)
183 {
184 	KMF_RETURN ret = KMF_OK;
185 	KMF_X509_EXTENSIONS *exts;
186 
187 	if (Csr == NULL || extn == NULL)
188 		return (KMF_ERR_BAD_PARAMETER);
189 
190 	exts = &Csr->csr.extensions;
191 
192 	ret = add_an_extension(exts, extn);
193 
194 	return (ret);
195 }
196 
197 KMF_RETURN
198 KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData,
199 	KMF_ALGORITHM_INDEX sigAlg)
200 {
201 	KMF_OID	*alg;
202 
203 	if (CsrData == NULL)
204 		return (KMF_ERR_BAD_PARAMETER);
205 
206 	alg = X509_AlgIdToAlgorithmOid(sigAlg);
207 
208 	if (alg != NULL) {
209 		(void) copy_data((KMF_DATA *)
210 			&CsrData->signature.algorithmIdentifier.algorithm,
211 			(KMF_DATA *)alg);
212 		(void) copy_data(
213 		    &CsrData->signature.algorithmIdentifier.parameters,
214 		    &CsrData->csr.subjectPublicKeyInfo.algorithm.parameters);
215 	} else {
216 		return (KMF_ERR_BAD_PARAMETER);
217 	}
218 	return (KMF_OK);
219 }
220 
221 KMF_RETURN
222 KMF_SetCSRSubjectAltName(KMF_CSR_DATA *Csr,
223 	char *altname, int critical,
224 	KMF_GENERALNAMECHOICES alttype)
225 {
226 	KMF_RETURN ret = KMF_OK;
227 
228 	if (Csr == NULL || altname == NULL)
229 		return (KMF_ERR_BAD_PARAMETER);
230 
231 	ret = KMF_SetAltName(&Csr->csr.extensions,
232 		(KMF_OID *)&KMFOID_SubjectAltName, critical, alttype,
233 		altname);
234 
235 	return (ret);
236 }
237 
238 KMF_RETURN
239 KMF_SetCSRKeyUsage(KMF_CSR_DATA *CSRData,
240 	int critical, uint16_t kubits)
241 {
242 	KMF_RETURN ret = KMF_OK;
243 
244 	if (CSRData == NULL)
245 		return (KMF_ERR_BAD_PARAMETER);
246 
247 	ret = set_key_usage_extension(
248 		&CSRData->csr.extensions,
249 		critical, kubits);
250 
251 	return (ret);
252 }
253 
254 /*
255  *
256  * Name: KMF_SignCSR
257  *
258  * Description:
259  *   This function signs a CSR and returns the result as a
260  *   signed, encoded CSR in SignedCsr
261  *
262  * Parameters:
263  *   tbsCsr(input) - pointer to a KMF_DATA structure containing a
264  *		DER encoded TBS CSR data
265  *   Signkey(input) - pointer to the KMF_KEY_HANDLE structure containing
266  *		the private key generated by the plug-in CreateKeypair
267  *   algo(input) - contains algorithm info needed for signing
268  *   SignedCsr(output) - pointer to the KMF_DATA structure containing
269  *		the signed CSR
270  *
271  * Returns:
272  *   A KMF_RETURN value indicating success or specifying a particular
273  *   error condition.
274  *   The value KMF_OK indicates success. All other values represent
275  *   an error condition.
276  *
277  */
278 KMF_RETURN
279 KMF_SignCSR(KMF_HANDLE_T handle,
280 	const KMF_CSR_DATA *tbsCsr,
281 	KMF_KEY_HANDLE	*Signkey,
282 	KMF_DATA	*SignedCsr)
283 {
284 	KMF_RETURN err;
285 	KMF_DATA csrdata = { NULL, 0 };
286 
287 	CLEAR_ERROR(handle, err);
288 	if (err != KMF_OK)
289 		return (err);
290 
291 	if (tbsCsr == NULL ||
292 		Signkey == NULL || SignedCsr == NULL)
293 		return (KMF_ERR_BAD_PARAMETER);
294 
295 	SignedCsr->Data = NULL;
296 	SignedCsr->Length = 0;
297 
298 	err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata);
299 	if (err == KMF_OK) {
300 		err = SignCsr(handle, &csrdata, Signkey,
301 			(KMF_X509_ALGORITHM_IDENTIFIER *)
302 				&tbsCsr->signature.algorithmIdentifier,
303 			SignedCsr);
304 	}
305 
306 	if (err != KMF_OK) {
307 		KMF_FreeData(SignedCsr);
308 	}
309 	KMF_FreeData(&csrdata);
310 	return (err);
311 }
312 
313 KMF_RETURN
314 KMF_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params)
315 {
316 	KMF_PLUGIN *plugin;
317 	KMF_RETURN ret;
318 
319 	CLEAR_ERROR(handle, ret);
320 	if (ret != KMF_OK)
321 		return (ret);
322 
323 	if (params == NULL)
324 		return (KMF_ERR_BAD_PARAMETER);
325 
326 	switch (params->kstype) {
327 	case KMF_KEYSTORE_NSS:
328 		plugin = FindPlugin(handle, params->kstype);
329 		break;
330 
331 	case KMF_KEYSTORE_OPENSSL:
332 	case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
333 		plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
334 		break;
335 	default:
336 		return (KMF_ERR_PLUGIN_NOTFOUND);
337 	}
338 
339 	if (plugin != NULL && plugin->funclist->ImportCRL != NULL) {
340 		return (plugin->funclist->ImportCRL(handle, params));
341 	}
342 	return (KMF_ERR_PLUGIN_NOTFOUND);
343 }
344 
345 KMF_RETURN
346 KMF_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params)
347 {
348 	KMF_PLUGIN *plugin;
349 	KMF_RETURN ret;
350 
351 	CLEAR_ERROR(handle, ret);
352 	if (ret != KMF_OK)
353 		return (ret);
354 
355 	if (params == NULL)
356 		return (KMF_ERR_BAD_PARAMETER);
357 
358 	switch (params->kstype) {
359 	case KMF_KEYSTORE_NSS:
360 		plugin = FindPlugin(handle, params->kstype);
361 		break;
362 
363 	case KMF_KEYSTORE_OPENSSL:
364 	case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
365 		plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
366 		break;
367 	default:
368 		return (KMF_ERR_PLUGIN_NOTFOUND);
369 	}
370 
371 	if (plugin != NULL && plugin->funclist->DeleteCRL != NULL) {
372 		return (plugin->funclist->DeleteCRL(handle, params));
373 	} else {
374 		return (KMF_ERR_PLUGIN_NOTFOUND);
375 	}
376 }
377 
378 KMF_RETURN
379 KMF_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, char **crldata)
380 {
381 	KMF_PLUGIN *plugin;
382 	KMF_RETURN ret;
383 
384 	CLEAR_ERROR(handle, ret);
385 	if (ret != KMF_OK)
386 		return (ret);
387 
388 	if (params == NULL || crldata == NULL)
389 		return (KMF_ERR_BAD_PARAMETER);
390 
391 	switch (params->kstype) {
392 	case KMF_KEYSTORE_NSS:
393 		plugin = FindPlugin(handle, params->kstype);
394 		break;
395 
396 	case KMF_KEYSTORE_OPENSSL:
397 	case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
398 		plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
399 		break;
400 	default:
401 		return (KMF_ERR_PLUGIN_NOTFOUND);
402 	}
403 
404 	if (plugin != NULL && plugin->funclist->ListCRL != NULL) {
405 		return (plugin->funclist->ListCRL(handle, params, crldata));
406 	} else {
407 		return (KMF_ERR_PLUGIN_NOTFOUND);
408 	}
409 }
410 
411 KMF_RETURN
412 KMF_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params,
413 	char **CRLNameList, int *CRLCount)
414 {
415 	KMF_PLUGIN *plugin;
416 	KMF_RETURN ret;
417 
418 	CLEAR_ERROR(handle, ret);
419 	if (ret != KMF_OK)
420 		return (ret);
421 
422 	if (params == NULL ||
423 		CRLCount == NULL)
424 		return (KMF_ERR_BAD_PARAMETER);
425 
426 	plugin = FindPlugin(handle, params->kstype);
427 	if (plugin != NULL && plugin->funclist->FindCRL != NULL) {
428 		return (plugin->funclist->FindCRL(handle, params,
429 			CRLNameList, CRLCount));
430 	} else {
431 		return (KMF_ERR_PLUGIN_NOTFOUND);
432 	}
433 }
434 
435 KMF_RETURN
436 KMF_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params)
437 {
438 	KMF_PLUGIN *plugin;
439 	KMF_RETURN ret;
440 
441 	CLEAR_ERROR(handle, ret);
442 	if (ret != KMF_OK)
443 		return (ret);
444 
445 	if (params == NULL)
446 		return (KMF_ERR_BAD_PARAMETER);
447 
448 	switch (params->kstype) {
449 	case KMF_KEYSTORE_NSS:
450 		plugin = FindPlugin(handle, params->kstype);
451 		break;
452 
453 	case KMF_KEYSTORE_OPENSSL:
454 	case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
455 		plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
456 		break;
457 	default:
458 		return (KMF_ERR_PLUGIN_NOTFOUND);
459 	}
460 
461 	if (plugin != NULL && plugin->funclist->FindCertInCRL != NULL) {
462 		return (plugin->funclist->FindCertInCRL(handle, params));
463 	} else {
464 		return (KMF_ERR_PLUGIN_NOTFOUND);
465 	}
466 }
467 
468 KMF_RETURN
469 KMF_VerifyCRLFile(KMF_HANDLE_T handle,
470 	KMF_VERIFYCRL_PARAMS *params)
471 {
472 	KMF_PLUGIN *plugin;
473 	KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T,
474 		KMF_VERIFYCRL_PARAMS *);
475 	KMF_RETURN ret;
476 
477 	CLEAR_ERROR(handle, ret);
478 	if (ret != KMF_OK)
479 		return (ret);
480 
481 	if (params == NULL)
482 		return (KMF_ERR_BAD_PARAMETER);
483 
484 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
485 	if (plugin == NULL || plugin->dldesc == NULL) {
486 		return (KMF_ERR_PLUGIN_NOTFOUND);
487 	}
488 
489 	verifyCRLFile = (KMF_RETURN(*)())dlsym(plugin->dldesc,
490 	    "OpenSSL_VerifyCRLFile");
491 
492 	if (verifyCRLFile == NULL) {
493 		return (KMF_ERR_FUNCTION_NOT_FOUND);
494 	}
495 
496 	return (verifyCRLFile(handle, params));
497 }
498 
499 KMF_RETURN
500 KMF_CheckCRLDate(KMF_HANDLE_T handle, KMF_CHECKCRLDATE_PARAMS *params)
501 {
502 	KMF_PLUGIN *plugin;
503 	KMF_RETURN (*checkCRLDate)(void *,
504 	    KMF_CHECKCRLDATE_PARAMS *params);
505 	KMF_RETURN ret;
506 
507 	CLEAR_ERROR(handle, ret);
508 	if (ret != KMF_OK)
509 		return (ret);
510 
511 	if (params == NULL)
512 		return (KMF_ERR_BAD_PARAMETER);
513 
514 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
515 	if (plugin == NULL || plugin->dldesc == NULL) {
516 		return (KMF_ERR_PLUGIN_NOTFOUND);
517 	}
518 
519 	checkCRLDate = (KMF_RETURN(*)())dlsym(plugin->dldesc,
520 	    "OpenSSL_CheckCRLDate");
521 
522 	if (checkCRLDate == NULL) {
523 		return (KMF_ERR_FUNCTION_NOT_FOUND);
524 	}
525 
526 	return (checkCRLDate(handle, params));
527 
528 }
529 
530 KMF_RETURN
531 KMF_IsCRLFile(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat)
532 {
533 	KMF_PLUGIN *plugin;
534 	KMF_RETURN (*IsCRLFileFn)(void *, char *, KMF_ENCODE_FORMAT *);
535 	KMF_RETURN ret;
536 
537 	CLEAR_ERROR(handle, ret);
538 	if (ret != KMF_OK)
539 		return (ret);
540 
541 	if (filename  == NULL || pformat == NULL) {
542 		return (KMF_ERR_BAD_PARAMETER);
543 	}
544 
545 	/*
546 	 * This framework function is actually implemented in the openssl
547 	 * plugin library, so we find the function address and call it.
548 	 */
549 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
550 	if (plugin == NULL || plugin->dldesc == NULL) {
551 		return (KMF_ERR_PLUGIN_NOTFOUND);
552 	}
553 
554 	IsCRLFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
555 	    "OpenSSL_IsCRLFile");
556 	if (IsCRLFileFn == NULL) {
557 		return (KMF_ERR_FUNCTION_NOT_FOUND);
558 	}
559 
560 	return (IsCRLFileFn(handle, filename, pformat));
561 }
562