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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * This file includes interfaces to be used together with SSL to get PKCS#12 24 * certs and pass them to SSL. They replace similar functions for PEM, 25 * already provided for within SSL. 26 * 27 * The interfaces included here are: 28 * sunw_p12_use_certfile - gets the user's cert from a pkcs12 file & pass 29 * it to SSL. 30 * sunw_p12_use_keyfile - gets the RSA private key from a pkcs12 file and 31 * pass it to SSL 32 * sunw_p12_use_trustfile - read the pkcs12 trust anchor (aka certificate 33 * authority certs) file into memory and hand them off to SSL. 34 * 35 * These functions use the sunw_PKCS12_parse to read the certs. 36 * 37 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 38 * Use is subject to license terms. 39 */ 40 41 #pragma ident "%Z%%M% %I% %E% SMI" 42 43 #include <stdio.h> 44 #include <strings.h> 45 #include <stdlib.h> 46 #include <sys/stat.h> 47 #include <unistd.h> 48 49 #include <openssl/crypto.h> 50 #include <openssl/err.h> 51 #include <openssl/x509.h> 52 #include <openssl/ssl.h> 53 54 #include <openssl/pkcs12.h> 55 #include <p12access.h> 56 #include <p12err.h> 57 58 static PKCS12 *p12_read_file(char *); 59 static int p12_doparse(PKCS12 *, char *, int, EVP_PKEY **, 60 X509 **, STACK_OF(X509) **); 61 static int checkfile(char *); 62 static int check_password(PKCS12 *, char *); 63 64 /* 65 * sunw_use_x509cert - pass an x509 client certificate to ssl 66 * 67 * Arguments: 68 * ctx - SSL's context structure 69 * cert - Certificate to pass in x509 format 70 * 71 * Returns: 72 * <=0 - Error occurred. Check the error stack for specifics. 73 * >0 - Success. Cert was successfully added. 74 */ 75 static int 76 sunw_use_x509cert(SSL_CTX *ctx, X509 *cert) 77 { 78 ERR_clear_error(); 79 80 if (ctx == NULL || cert == NULL) { 81 SUNWerr(SUNW_F_USE_X509CERT, SUNW_R_INVALID_ARG); 82 return (-1); 83 } 84 85 if (SSL_CTX_use_certificate(ctx, cert) != 1) { 86 SUNWerr(SUNW_F_USE_X509CERT, SUNW_R_CERT_ERR); 87 return (-1); 88 } 89 return (1); 90 } 91 92 /* 93 * sunw_use_pkey - pass an EVP_PKEY private key to ssl 94 * 95 * Arguments: 96 * ctx - SSL's context structure 97 * pkey - EVP_PKEY formatted private key 98 * 99 * Returns: 100 * <=0 - Error occurred. Check the error stack for specifics. 101 * >0 - Success. 102 */ 103 static int 104 sunw_use_pkey(SSL_CTX *ctx, EVP_PKEY *pkey) 105 { 106 ERR_clear_error(); 107 if (ctx == NULL || pkey == NULL) { 108 SUNWerr(SUNW_F_USE_PKEY, SUNW_R_INVALID_ARG); 109 return (-1); 110 } 111 112 if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) { 113 SUNWerr(SUNW_F_USE_PKEY, SUNW_R_PKEY_ERR); 114 return (-1); 115 } 116 117 return (1); 118 } 119 120 /* 121 * sunw_use_tastore - take a stack of X509 certs and add them to the 122 * SSL store of trust anchors (aka CA certs). 123 * 124 * This function takes the certs in the stack and passes them into 125 * SSL for addition to the cache of TA certs. 126 * 127 * Arguments: 128 * ctx - SSL's context structure 129 * ta_certs - Stack of certs to add to the list of SSL trust anchors. 130 * 131 * Returns: 132 * <=0 - Error occurred. Check the error stack for specifics. 133 * >0 - Success. Certs were successfully added. 134 */ 135 static int 136 sunw_use_tastore(SSL_CTX *ctx, STACK_OF(X509) *ta_certs) 137 { 138 X509 *tmp; 139 int ret = -1; 140 int i; 141 142 ERR_clear_error(); 143 if (ctx == NULL || ctx->cert_store == NULL || ta_certs == NULL) { 144 SUNWerr(SUNW_F_USE_TASTORE, SUNW_R_INVALID_ARG); 145 return (-1); 146 } 147 148 if (sk_X509_num(ta_certs) == 0) { 149 SUNWerr(SUNW_F_USE_TASTORE, SUNW_R_NO_TRUST_ANCHOR); 150 return (-1); 151 } 152 153 for (i = 0; i < sk_X509_num(ta_certs); i++) { 154 tmp = sk_X509_value(ta_certs, i); 155 156 ret = X509_STORE_add_cert(ctx->cert_store, tmp); 157 if (ret == 0) { 158 if (ERR_GET_REASON(ERR_peek_error()) == 159 X509_R_CERT_ALREADY_IN_HASH_TABLE) { 160 ERR_clear_error(); 161 continue; 162 } 163 SUNWerr(SUNW_F_USE_TASTORE, SUNW_R_ADD_TRUST_ERR); 164 return (-1); 165 } else if (ret < 0) { 166 break; 167 } 168 } 169 170 if (ret < 0) { 171 SUNWerr(SUNW_F_USE_TASTORE, SUNW_R_ADD_TRUST_ERR); 172 } 173 174 return (ret); 175 } 176 177 /* 178 * sunw_p12_use_certfile - read a client certificate from a pkcs12 file and 179 * pass it in to SSL. 180 * 181 * Read in the certificate in pkcs12-formated file. Use the provided 182 * passphrase to decrypt it. Pass the cert to SSL. 183 * 184 * Arguments: 185 * ctx - SSL's context structure 186 * filename - Name of file with the client certificate. 187 * passwd - Passphrase for pkcs12 data. 188 * 189 * Returns: 190 * <=0 - Error occurred. Check the error stack for specifics. 191 * >0 - Success. Cert was successfully added. 192 */ 193 int 194 sunw_p12_use_certfile(SSL_CTX *ctx, char *filename, char *passwd) 195 { 196 PKCS12 *p12 = NULL; 197 X509 *cert = NULL; 198 int ret = -1; 199 200 ERR_clear_error(); 201 if (ctx == NULL || filename == NULL) { 202 SUNWerr(SUNW_F_USE_CERTFILE, SUNW_R_INVALID_ARG); 203 return (-1); 204 } 205 206 p12 = p12_read_file(filename); 207 if (p12 != NULL) { 208 ret = p12_doparse(p12, passwd, DO_UNMATCHING, NULL, 209 &cert, NULL); 210 if (ret > 0 && cert != NULL) { 211 if (sunw_use_x509cert(ctx, cert) == -1) { 212 /* 213 * Error already on stack 214 */ 215 ret = -1; 216 } 217 } 218 } 219 220 if (p12 != NULL) 221 PKCS12_free(p12); 222 223 if (ret == -1 && cert != NULL) { 224 X509_free(cert); 225 cert = NULL; 226 } 227 228 return (ret); 229 } 230 231 /* 232 * sunw_p12_use_keyfile - read a RSA private key from a pkcs12 file and pass 233 * it in to SSL. 234 * 235 * Read in the RSA private key in pkcs12 format. Use the provided 236 * passphrase to decrypt it. Pass the cert to SSL. 237 * 238 * Arguments: 239 * ctx - SSL's context structure 240 * filename - Name of file with private key. 241 * passwd - Passphrase for pkcs12 data. 242 * 243 * Returns: 244 * <=0 - Error occurred. Check the error stack for specifics. 245 * >0 - Success. Key was successfully added. 246 */ 247 int 248 sunw_p12_use_keyfile(SSL_CTX *ctx, char *filename, char *passwd) 249 { 250 EVP_PKEY *pkey = NULL; 251 PKCS12 *p12 = NULL; 252 int ret = -1; 253 254 ERR_clear_error(); 255 if (ctx == NULL || filename == NULL) { 256 SUNWerr(SUNW_F_USE_KEYFILE, SUNW_R_INVALID_ARG); 257 return (-1); 258 } 259 260 p12 = p12_read_file(filename); 261 if (p12 != NULL) { 262 ret = p12_doparse(p12, passwd, DO_UNMATCHING, &pkey, NULL, 263 NULL); 264 if (ret > 0 && pkey != NULL) { 265 if (sunw_use_pkey(ctx, pkey) != 1) { 266 /* 267 * Error already on stack 268 */ 269 ret = -1; 270 } 271 } else { 272 SUNWerr(SUNW_F_USE_KEYFILE, SUNW_R_BAD_PKEY); 273 } 274 } else { 275 SUNWerr(SUNW_F_USE_KEYFILE, SUNW_R_PKEY_READ_ERR); 276 } 277 278 if (p12 != NULL) 279 PKCS12_free(p12); 280 281 if (ret == -1 && pkey != NULL) { 282 sunw_evp_pkey_free(pkey); 283 pkey = NULL; 284 } 285 286 return (ret); 287 } 288 289 /* 290 * sunw_p12_use_trustfile - read a list of trustanchors from a pkcs12 file and 291 * pass the stack in to SSL. 292 * 293 * Read in the trust anchors from pkcs12-formated file. Use the provided 294 * passphrase to decrypt it. Pass the cert to SSL. 295 * 296 * Arguments: 297 * ctx - SSL's context structure 298 * filename - Name of file with the certificates. 299 * passwd - Passphrase for pkcs12 data. 300 * 301 * Returns: 302 * <=0 - Error occurred. Check the error stack for specifics. 303 * >0 - Success. Trust anchors were successfully added. 304 */ 305 int 306 sunw_p12_use_trustfile(SSL_CTX *ctx, char *filename, char *passwd) 307 { 308 PKCS12 *p12 = NULL; 309 STACK_OF(X509) *ta_sk = NULL; 310 int ret = -1; 311 312 ERR_clear_error(); 313 if (ctx == NULL || filename == NULL) { 314 SUNWerr(SUNW_F_USE_TRUSTFILE, SUNW_R_INVALID_ARG); 315 return (-1); 316 } 317 318 p12 = p12_read_file(filename); 319 if (p12 != NULL) { 320 ret = p12_doparse(p12, passwd, DO_NONE, NULL, NULL, 321 &ta_sk); 322 if (ret > 0 && ta_sk != NULL) 323 ret = sunw_use_tastore(ctx, ta_sk); 324 else { 325 SUNWerr(SUNW_F_USE_TRUSTFILE, SUNW_R_BAD_TRUST); 326 ret = -1; 327 } 328 } else { 329 SUNWerr(SUNW_F_USE_TRUSTFILE, SUNW_R_READ_TRUST_ERR); 330 } 331 332 if (p12 != NULL) 333 PKCS12_free(p12); 334 335 if (ta_sk != NULL) 336 sk_X509_pop_free(ta_sk, X509_free); 337 338 return (ret); 339 } 340 341 /* 342 * p12_read_file - read a pkcs12 file and get its contents. Return the 343 * pkcs12 structures. 344 * 345 * Arguments: 346 * filename - Name of file with the client certificate. 347 * 348 * 349 * Returns: 350 * NULL - Error occurred. Check the error stack for specifics. 351 * != NULL - Success. The return value is the address of a pkcs12 352 * structure. 353 */ 354 static PKCS12 * 355 p12_read_file(char *filename) 356 { 357 PKCS12 *p12 = NULL; 358 FILE *fp = NULL; 359 int ret = 0; 360 361 ERR_clear_error(); 362 if (checkfile(filename) == -1) { 363 /* 364 * Error already on stack 365 */ 366 return (NULL); 367 } 368 369 if ((fp = fopen(filename, "r")) == 0) { 370 SYSerr(SYS_F_FOPEN, errno); 371 return (NULL); 372 } 373 374 p12 = d2i_PKCS12_fp(fp, NULL); 375 if (p12 == NULL) { 376 SUNWerr(SUNW_F_READ_FILE, SUNW_R_READ_ERR); 377 ret = -1; 378 } 379 380 if (fp != NULL) 381 (void) fclose(fp); 382 383 if (ret == -1 && p12 != NULL) { 384 PKCS12_free(p12); 385 p12 = NULL; 386 } 387 388 return (p12); 389 } 390 391 /* 392 * p12_doparse - Given a pkcs12 structure, check the passphrase and then 393 * parse it. 394 * 395 * Arguments: 396 * p12 - Structure with pkcs12 data which has been read in 397 * passwd - Passphrase for pkcs12 data & key. 398 * matchty - How to decide which matching entry to take... See the 399 * DO_* definitions for valid values. 400 * pkey - Points at pointer to private key structure. 401 * cert - Points at pointer to client certificate structure 402 * ca - Points at pointer to list of CA certs 403 * 404 * Returns: 405 * <=0 - Error occurred. Check the error stack for specifics. 406 * >0 - Success. Bits set reflect the kind of information 407 * returned. (See the FOUND_* definitions.) 408 */ 409 static int 410 p12_doparse(PKCS12 *p12, char *passwd, int matchty, 411 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) 412 { 413 int ret = 0; 414 415 ERR_clear_error(); 416 417 /* 418 * Check passphrase (including null one). 419 */ 420 if (check_password(p12, passwd) == 0) { 421 SUNWerr(SUNW_F_DOPARSE, SUNW_R_MAC_VERIFY_FAILURE); 422 return (-1); 423 } 424 425 ret = sunw_PKCS12_parse(p12, passwd, matchty, NULL, 0, NULL, 426 pkey, cert, ca); 427 if (ret <= 0) { 428 /* 429 * Error already on stack 430 */ 431 return (-1); 432 } 433 434 return (ret); 435 } 436 437 /* 438 * checkfile - given a file name, verify that the file exists and is 439 * readable. 440 */ 441 /* ARGSUSED */ 442 static int 443 checkfile(char *filename) 444 { 445 #ifndef _BOOT 446 struct stat sbuf; 447 448 if (access(filename, R_OK) == -1 || stat(filename, &sbuf) == -1) { 449 SYSerr(SYS_F_FOPEN, errno); 450 return (-1); 451 } 452 453 if (!S_ISREG(sbuf.st_mode)) { 454 SUNWerr(SUNW_F_CHECKFILE, SUNW_R_BAD_FILETYPE); 455 return (-1); 456 } 457 #endif 458 return (0); 459 } 460 461 /* 462 * check_password - do various password checks to see if the current password 463 * will work or we need to prompt for a new one. 464 * 465 * Arguments: 466 * pass - password to check 467 * 468 * Returns: 469 * 1 - Password is OK. 470 * 0 - Password not valid. Error stack was set - use ERR_get_error() to 471 * to get the error. 472 */ 473 static int 474 check_password(PKCS12 *p12, char *pass) 475 { 476 int ret = 1; 477 478 /* 479 * If password is zero length or NULL then try verifying both cases 480 * to determine which password is correct. The reason for this is that 481 * under PKCS#12 password based encryption no password and a zero 482 * length password are two different things. Otherwise, calling 483 * PKCS12_verify_mac() with a length of -1 means that the length 484 * can be determined via strlen(). 485 */ 486 /* Check the mac */ 487 if (pass == NULL || *pass == '\0') { 488 if (PKCS12_verify_mac(p12, NULL, 0) == 0 && 489 PKCS12_verify_mac(p12, "", 0) == 0) 490 ret = 0; 491 } else if (PKCS12_verify_mac(p12, pass, -1) == 0) { 492 ret = 0; 493 } 494 495 return (ret); 496 } 497