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 KMF_RETURN rv = KMF_OK; 123 KMF_X509_NAME *temp_name_ptr = NULL; 124 125 if (CsrData != NULL && subject_name_ptr != NULL) { 126 rv = CopyRDN(subject_name_ptr, &temp_name_ptr); 127 if (rv == KMF_OK) { 128 CsrData->csr.subject = *temp_name_ptr; 129 } 130 } else { 131 return (KMF_ERR_BAD_PARAMETER); 132 } 133 return (rv); 134 } 135 136 KMF_RETURN 137 KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format, 138 char *csrfile) 139 { 140 KMF_RETURN rv = KMF_OK; 141 int fd = -1; 142 KMF_DATA pemdata = {NULL, 0}; 143 144 if (csrdata == NULL || csrfile == NULL) 145 return (KMF_ERR_BAD_PARAMETER); 146 147 if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1) 148 return (KMF_ERR_BAD_PARAMETER); 149 150 if (format == KMF_FORMAT_PEM) { 151 int len; 152 rv = KMF_Der2Pem(KMF_CSR, 153 csrdata->Data, csrdata->Length, 154 &pemdata.Data, &len); 155 if (rv != KMF_OK) 156 goto cleanup; 157 pemdata.Length = (size_t)len; 158 } 159 160 if ((fd = open(csrfile, O_CREAT |O_RDWR, 0644)) == -1) { 161 rv = KMF_ERR_OPEN_FILE; 162 goto cleanup; 163 } 164 165 if (format == KMF_FORMAT_PEM) { 166 if (write(fd, pemdata.Data, pemdata.Length) != 167 pemdata.Length) { 168 rv = KMF_ERR_WRITE_FILE; 169 } 170 } else { 171 if (write(fd, csrdata->Data, csrdata->Length) != 172 csrdata->Length) { 173 rv = KMF_ERR_WRITE_FILE; 174 } 175 } 176 177 cleanup: 178 if (fd != -1) 179 (void) close(fd); 180 181 KMF_FreeData(&pemdata); 182 183 return (rv); 184 } 185 186 KMF_RETURN 187 KMF_SetCSRExtension(KMF_CSR_DATA *Csr, 188 KMF_X509_EXTENSION *extn) 189 { 190 KMF_RETURN ret = KMF_OK; 191 KMF_X509_EXTENSIONS *exts; 192 193 if (Csr == NULL || extn == NULL) 194 return (KMF_ERR_BAD_PARAMETER); 195 196 exts = &Csr->csr.extensions; 197 198 ret = add_an_extension(exts, extn); 199 200 return (ret); 201 } 202 203 KMF_RETURN 204 KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData, 205 KMF_ALGORITHM_INDEX sigAlg) 206 { 207 KMF_OID *alg; 208 209 if (CsrData == NULL) 210 return (KMF_ERR_BAD_PARAMETER); 211 212 alg = X509_AlgIdToAlgorithmOid(sigAlg); 213 214 if (alg != NULL) { 215 (void) copy_data((KMF_DATA *) 216 &CsrData->signature.algorithmIdentifier.algorithm, 217 (KMF_DATA *)alg); 218 (void) copy_data( 219 &CsrData->signature.algorithmIdentifier.parameters, 220 &CsrData->csr.subjectPublicKeyInfo.algorithm.parameters); 221 } else { 222 return (KMF_ERR_BAD_PARAMETER); 223 } 224 return (KMF_OK); 225 } 226 227 KMF_RETURN 228 KMF_SetCSRSubjectAltName(KMF_CSR_DATA *Csr, 229 char *altname, int critical, 230 KMF_GENERALNAMECHOICES alttype) 231 { 232 KMF_RETURN ret = KMF_OK; 233 234 if (Csr == NULL || altname == NULL) 235 return (KMF_ERR_BAD_PARAMETER); 236 237 ret = KMF_SetAltName(&Csr->csr.extensions, 238 (KMF_OID *)&KMFOID_SubjectAltName, critical, alttype, 239 altname); 240 241 return (ret); 242 } 243 244 KMF_RETURN 245 KMF_SetCSRKeyUsage(KMF_CSR_DATA *CSRData, 246 int critical, uint16_t kubits) 247 { 248 KMF_RETURN ret = KMF_OK; 249 250 if (CSRData == NULL) 251 return (KMF_ERR_BAD_PARAMETER); 252 253 ret = set_key_usage_extension( 254 &CSRData->csr.extensions, 255 critical, kubits); 256 257 return (ret); 258 } 259 260 /* 261 * 262 * Name: KMF_SignCSR 263 * 264 * Description: 265 * This function signs a CSR and returns the result as a 266 * signed, encoded CSR in SignedCsr 267 * 268 * Parameters: 269 * tbsCsr(input) - pointer to a KMF_DATA structure containing a 270 * DER encoded TBS CSR data 271 * Signkey(input) - pointer to the KMF_KEY_HANDLE structure containing 272 * the private key generated by the plug-in CreateKeypair 273 * algo(input) - contains algorithm info needed for signing 274 * SignedCsr(output) - pointer to the KMF_DATA structure containing 275 * the signed CSR 276 * 277 * Returns: 278 * A KMF_RETURN value indicating success or specifying a particular 279 * error condition. 280 * The value KMF_OK indicates success. All other values represent 281 * an error condition. 282 * 283 */ 284 KMF_RETURN 285 KMF_SignCSR(KMF_HANDLE_T handle, 286 const KMF_CSR_DATA *tbsCsr, 287 KMF_KEY_HANDLE *Signkey, 288 KMF_DATA *SignedCsr) 289 { 290 KMF_RETURN err; 291 KMF_DATA csrdata = { NULL, 0 }; 292 293 CLEAR_ERROR(handle, err); 294 if (err != KMF_OK) 295 return (err); 296 297 if (tbsCsr == NULL || 298 Signkey == NULL || SignedCsr == NULL) 299 return (KMF_ERR_BAD_PARAMETER); 300 301 SignedCsr->Data = NULL; 302 SignedCsr->Length = 0; 303 304 err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata); 305 if (err == KMF_OK) { 306 err = SignCsr(handle, &csrdata, Signkey, 307 (KMF_X509_ALGORITHM_IDENTIFIER *) 308 &tbsCsr->signature.algorithmIdentifier, 309 SignedCsr); 310 } 311 312 if (err != KMF_OK) { 313 KMF_FreeData(SignedCsr); 314 } 315 KMF_FreeData(&csrdata); 316 return (err); 317 } 318 319 KMF_RETURN 320 KMF_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 321 { 322 KMF_PLUGIN *plugin; 323 KMF_RETURN ret; 324 325 CLEAR_ERROR(handle, ret); 326 if (ret != KMF_OK) 327 return (ret); 328 329 if (params == NULL) 330 return (KMF_ERR_BAD_PARAMETER); 331 332 switch (params->kstype) { 333 case KMF_KEYSTORE_NSS: 334 plugin = FindPlugin(handle, params->kstype); 335 break; 336 337 case KMF_KEYSTORE_OPENSSL: 338 case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ 339 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 340 break; 341 default: 342 return (KMF_ERR_PLUGIN_NOTFOUND); 343 } 344 345 if (plugin != NULL && plugin->funclist->ImportCRL != NULL) { 346 return (plugin->funclist->ImportCRL(handle, params)); 347 } 348 return (KMF_ERR_PLUGIN_NOTFOUND); 349 } 350 351 KMF_RETURN 352 KMF_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 353 { 354 KMF_PLUGIN *plugin; 355 KMF_RETURN ret; 356 357 CLEAR_ERROR(handle, ret); 358 if (ret != KMF_OK) 359 return (ret); 360 361 if (params == NULL) 362 return (KMF_ERR_BAD_PARAMETER); 363 364 switch (params->kstype) { 365 case KMF_KEYSTORE_NSS: 366 plugin = FindPlugin(handle, params->kstype); 367 break; 368 369 case KMF_KEYSTORE_OPENSSL: 370 case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ 371 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 372 break; 373 default: 374 return (KMF_ERR_PLUGIN_NOTFOUND); 375 } 376 377 if (plugin != NULL && plugin->funclist->DeleteCRL != NULL) { 378 return (plugin->funclist->DeleteCRL(handle, params)); 379 } else { 380 return (KMF_ERR_PLUGIN_NOTFOUND); 381 } 382 } 383 384 KMF_RETURN 385 KMF_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, char **crldata) 386 { 387 KMF_PLUGIN *plugin; 388 KMF_RETURN ret; 389 390 CLEAR_ERROR(handle, ret); 391 if (ret != KMF_OK) 392 return (ret); 393 394 if (params == NULL || crldata == NULL) 395 return (KMF_ERR_BAD_PARAMETER); 396 397 switch (params->kstype) { 398 case KMF_KEYSTORE_NSS: 399 plugin = FindPlugin(handle, params->kstype); 400 break; 401 402 case KMF_KEYSTORE_OPENSSL: 403 case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ 404 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 405 break; 406 default: 407 return (KMF_ERR_PLUGIN_NOTFOUND); 408 } 409 410 if (plugin != NULL && plugin->funclist->ListCRL != NULL) { 411 return (plugin->funclist->ListCRL(handle, params, crldata)); 412 } else { 413 return (KMF_ERR_PLUGIN_NOTFOUND); 414 } 415 } 416 417 KMF_RETURN 418 KMF_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params, 419 char **CRLNameList, int *CRLCount) 420 { 421 KMF_PLUGIN *plugin; 422 KMF_RETURN ret; 423 424 CLEAR_ERROR(handle, ret); 425 if (ret != KMF_OK) 426 return (ret); 427 428 if (params == NULL || 429 CRLCount == NULL) 430 return (KMF_ERR_BAD_PARAMETER); 431 432 plugin = FindPlugin(handle, params->kstype); 433 if (plugin != NULL && plugin->funclist->FindCRL != NULL) { 434 return (plugin->funclist->FindCRL(handle, params, 435 CRLNameList, CRLCount)); 436 } else { 437 return (KMF_ERR_PLUGIN_NOTFOUND); 438 } 439 } 440 441 KMF_RETURN 442 KMF_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 443 { 444 KMF_PLUGIN *plugin; 445 KMF_RETURN ret; 446 447 CLEAR_ERROR(handle, ret); 448 if (ret != KMF_OK) 449 return (ret); 450 451 if (params == NULL) 452 return (KMF_ERR_BAD_PARAMETER); 453 454 switch (params->kstype) { 455 case KMF_KEYSTORE_NSS: 456 plugin = FindPlugin(handle, params->kstype); 457 break; 458 459 case KMF_KEYSTORE_OPENSSL: 460 case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */ 461 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 462 break; 463 default: 464 return (KMF_ERR_PLUGIN_NOTFOUND); 465 } 466 467 if (plugin != NULL && plugin->funclist->FindCertInCRL != NULL) { 468 return (plugin->funclist->FindCertInCRL(handle, params)); 469 } else { 470 return (KMF_ERR_PLUGIN_NOTFOUND); 471 } 472 } 473 474 KMF_RETURN 475 KMF_VerifyCRLFile(KMF_HANDLE_T handle, 476 KMF_VERIFYCRL_PARAMS *params) 477 { 478 KMF_PLUGIN *plugin; 479 KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T, 480 KMF_VERIFYCRL_PARAMS *); 481 KMF_RETURN ret; 482 483 CLEAR_ERROR(handle, ret); 484 if (ret != KMF_OK) 485 return (ret); 486 487 if (params == NULL) 488 return (KMF_ERR_BAD_PARAMETER); 489 490 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 491 if (plugin == NULL || plugin->dldesc == NULL) { 492 return (KMF_ERR_PLUGIN_NOTFOUND); 493 } 494 495 verifyCRLFile = (KMF_RETURN(*)())dlsym(plugin->dldesc, 496 "OpenSSL_VerifyCRLFile"); 497 498 if (verifyCRLFile == NULL) { 499 return (KMF_ERR_FUNCTION_NOT_FOUND); 500 } 501 502 return (verifyCRLFile(handle, params)); 503 } 504 505 KMF_RETURN 506 KMF_CheckCRLDate(KMF_HANDLE_T handle, KMF_CHECKCRLDATE_PARAMS *params) 507 { 508 KMF_PLUGIN *plugin; 509 KMF_RETURN (*checkCRLDate)(void *, 510 KMF_CHECKCRLDATE_PARAMS *params); 511 KMF_RETURN ret; 512 513 CLEAR_ERROR(handle, ret); 514 if (ret != KMF_OK) 515 return (ret); 516 517 if (params == NULL) 518 return (KMF_ERR_BAD_PARAMETER); 519 520 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 521 if (plugin == NULL || plugin->dldesc == NULL) { 522 return (KMF_ERR_PLUGIN_NOTFOUND); 523 } 524 525 checkCRLDate = (KMF_RETURN(*)())dlsym(plugin->dldesc, 526 "OpenSSL_CheckCRLDate"); 527 528 if (checkCRLDate == NULL) { 529 return (KMF_ERR_FUNCTION_NOT_FOUND); 530 } 531 532 return (checkCRLDate(handle, params)); 533 534 } 535 536 KMF_RETURN 537 KMF_IsCRLFile(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat) 538 { 539 KMF_PLUGIN *plugin; 540 KMF_RETURN (*IsCRLFileFn)(void *, char *, KMF_ENCODE_FORMAT *); 541 KMF_RETURN ret; 542 543 CLEAR_ERROR(handle, ret); 544 if (ret != KMF_OK) 545 return (ret); 546 547 if (filename == NULL || pformat == NULL) { 548 return (KMF_ERR_BAD_PARAMETER); 549 } 550 551 /* 552 * This framework function is actually implemented in the openssl 553 * plugin library, so we find the function address and call it. 554 */ 555 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 556 if (plugin == NULL || plugin->dldesc == NULL) { 557 return (KMF_ERR_PLUGIN_NOTFOUND); 558 } 559 560 IsCRLFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 561 "OpenSSL_IsCRLFile"); 562 if (IsCRLFileFn == NULL) { 563 return (KMF_ERR_FUNCTION_NOT_FOUND); 564 } 565 566 return (IsCRLFileFn(handle, filename, pformat)); 567 } 568