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