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
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.
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]
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.
27 * The interfaces included here are:
28 * sunw_p12_use_certfile - gets the user's cert from a pkcs12 file & pass
30 * sunw_p12_use_keyfile - gets the RSA private key from a pkcs12 file and
32 * sunw_p12_use_trustfile - read the pkcs12 trust anchor (aka certificate
33 * authority certs) file into memory and hand them off to SSL.
35 * These functions use the sunw_PKCS12_parse to read the certs.
37 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
38 * Use is subject to license terms.
41 #pragma ident "%Z%%M% %I% %E% SMI"
49 #include <openssl/crypto.h>
50 #include <openssl/err.h>
51 #include <openssl/x509.h>
52 #include <openssl/ssl.h>
54 #include <openssl/pkcs12.h>
55 #include <p12access.h>
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 *);
65 * sunw_use_x509cert - pass an x509 client certificate to ssl
68 * ctx - SSL's context structure
69 * cert - Certificate to pass in x509 format
72 * <=0 - Error occurred. Check the error stack for specifics.
73 * >0 - Success. Cert was successfully added.
76 sunw_use_x509cert(SSL_CTX
*ctx
, X509
*cert
)
80 if (ctx
== NULL
|| cert
== NULL
) {
81 SUNWerr(SUNW_F_USE_X509CERT
, SUNW_R_INVALID_ARG
);
85 if (SSL_CTX_use_certificate(ctx
, cert
) != 1) {
86 SUNWerr(SUNW_F_USE_X509CERT
, SUNW_R_CERT_ERR
);
93 * sunw_use_pkey - pass an EVP_PKEY private key to ssl
96 * ctx - SSL's context structure
97 * pkey - EVP_PKEY formatted private key
100 * <=0 - Error occurred. Check the error stack for specifics.
104 sunw_use_pkey(SSL_CTX
*ctx
, EVP_PKEY
*pkey
)
107 if (ctx
== NULL
|| pkey
== NULL
) {
108 SUNWerr(SUNW_F_USE_PKEY
, SUNW_R_INVALID_ARG
);
112 if (SSL_CTX_use_PrivateKey(ctx
, pkey
) != 1) {
113 SUNWerr(SUNW_F_USE_PKEY
, SUNW_R_PKEY_ERR
);
121 * sunw_use_tastore - take a stack of X509 certs and add them to the
122 * SSL store of trust anchors (aka CA certs).
124 * This function takes the certs in the stack and passes them into
125 * SSL for addition to the cache of TA certs.
128 * ctx - SSL's context structure
129 * ta_certs - Stack of certs to add to the list of SSL trust anchors.
132 * <=0 - Error occurred. Check the error stack for specifics.
133 * >0 - Success. Certs were successfully added.
136 sunw_use_tastore(SSL_CTX
*ctx
, STACK_OF(X509
) *ta_certs
)
143 if (ctx
== NULL
|| ctx
->cert_store
== NULL
|| ta_certs
== NULL
) {
144 SUNWerr(SUNW_F_USE_TASTORE
, SUNW_R_INVALID_ARG
);
148 if (sk_X509_num(ta_certs
) == 0) {
149 SUNWerr(SUNW_F_USE_TASTORE
, SUNW_R_NO_TRUST_ANCHOR
);
153 for (i
= 0; i
< sk_X509_num(ta_certs
); i
++) {
154 tmp
= sk_X509_value(ta_certs
, i
);
156 ret
= X509_STORE_add_cert(ctx
->cert_store
, tmp
);
158 if (ERR_GET_REASON(ERR_peek_error()) ==
159 X509_R_CERT_ALREADY_IN_HASH_TABLE
) {
163 SUNWerr(SUNW_F_USE_TASTORE
, SUNW_R_ADD_TRUST_ERR
);
165 } else if (ret
< 0) {
171 SUNWerr(SUNW_F_USE_TASTORE
, SUNW_R_ADD_TRUST_ERR
);
178 * sunw_p12_use_certfile - read a client certificate from a pkcs12 file and
181 * Read in the certificate in pkcs12-formated file. Use the provided
182 * passphrase to decrypt it. Pass the cert to SSL.
185 * ctx - SSL's context structure
186 * filename - Name of file with the client certificate.
187 * passwd - Passphrase for pkcs12 data.
190 * <=0 - Error occurred. Check the error stack for specifics.
191 * >0 - Success. Cert was successfully added.
194 sunw_p12_use_certfile(SSL_CTX
*ctx
, char *filename
, char *passwd
)
201 if (ctx
== NULL
|| filename
== NULL
) {
202 SUNWerr(SUNW_F_USE_CERTFILE
, SUNW_R_INVALID_ARG
);
206 p12
= p12_read_file(filename
);
208 ret
= p12_doparse(p12
, passwd
, DO_UNMATCHING
, NULL
,
210 if (ret
> 0 && cert
!= NULL
) {
211 if (sunw_use_x509cert(ctx
, cert
) == -1) {
213 * Error already on stack
223 if (ret
== -1 && cert
!= NULL
) {
232 * sunw_p12_use_keyfile - read a RSA private key from a pkcs12 file and pass
235 * Read in the RSA private key in pkcs12 format. Use the provided
236 * passphrase to decrypt it. Pass the cert to SSL.
239 * ctx - SSL's context structure
240 * filename - Name of file with private key.
241 * passwd - Passphrase for pkcs12 data.
244 * <=0 - Error occurred. Check the error stack for specifics.
245 * >0 - Success. Key was successfully added.
248 sunw_p12_use_keyfile(SSL_CTX
*ctx
, char *filename
, char *passwd
)
250 EVP_PKEY
*pkey
= NULL
;
255 if (ctx
== NULL
|| filename
== NULL
) {
256 SUNWerr(SUNW_F_USE_KEYFILE
, SUNW_R_INVALID_ARG
);
260 p12
= p12_read_file(filename
);
262 ret
= p12_doparse(p12
, passwd
, DO_UNMATCHING
, &pkey
, NULL
,
264 if (ret
> 0 && pkey
!= NULL
) {
265 if (sunw_use_pkey(ctx
, pkey
) != 1) {
267 * Error already on stack
272 SUNWerr(SUNW_F_USE_KEYFILE
, SUNW_R_BAD_PKEY
);
275 SUNWerr(SUNW_F_USE_KEYFILE
, SUNW_R_PKEY_READ_ERR
);
281 if (ret
== -1 && pkey
!= NULL
) {
282 sunw_evp_pkey_free(pkey
);
290 * sunw_p12_use_trustfile - read a list of trustanchors from a pkcs12 file and
291 * pass the stack in to SSL.
293 * Read in the trust anchors from pkcs12-formated file. Use the provided
294 * passphrase to decrypt it. Pass the cert to SSL.
297 * ctx - SSL's context structure
298 * filename - Name of file with the certificates.
299 * passwd - Passphrase for pkcs12 data.
302 * <=0 - Error occurred. Check the error stack for specifics.
303 * >0 - Success. Trust anchors were successfully added.
306 sunw_p12_use_trustfile(SSL_CTX
*ctx
, char *filename
, char *passwd
)
309 STACK_OF(X509
) *ta_sk
= NULL
;
313 if (ctx
== NULL
|| filename
== NULL
) {
314 SUNWerr(SUNW_F_USE_TRUSTFILE
, SUNW_R_INVALID_ARG
);
318 p12
= p12_read_file(filename
);
320 ret
= p12_doparse(p12
, passwd
, DO_NONE
, NULL
, NULL
,
322 if (ret
> 0 && ta_sk
!= NULL
)
323 ret
= sunw_use_tastore(ctx
, ta_sk
);
325 SUNWerr(SUNW_F_USE_TRUSTFILE
, SUNW_R_BAD_TRUST
);
329 SUNWerr(SUNW_F_USE_TRUSTFILE
, SUNW_R_READ_TRUST_ERR
);
336 sk_X509_pop_free(ta_sk
, X509_free
);
342 * p12_read_file - read a pkcs12 file and get its contents. Return the
346 * filename - Name of file with the client certificate.
350 * NULL - Error occurred. Check the error stack for specifics.
351 * != NULL - Success. The return value is the address of a pkcs12
355 p12_read_file(char *filename
)
362 if (checkfile(filename
) == -1) {
364 * Error already on stack
369 if ((fp
= fopen(filename
, "r")) == 0) {
370 SYSerr(SYS_F_FOPEN
, errno
);
374 p12
= d2i_PKCS12_fp(fp
, NULL
);
376 SUNWerr(SUNW_F_READ_FILE
, SUNW_R_READ_ERR
);
383 if (ret
== -1 && p12
!= NULL
) {
392 * p12_doparse - Given a pkcs12 structure, check the passphrase and then
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
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.)
410 p12_doparse(PKCS12
*p12
, char *passwd
, int matchty
,
411 EVP_PKEY
**pkey
, X509
**cert
, STACK_OF(X509
) **ca
)
418 * Check passphrase (including null one).
420 if (check_password(p12
, passwd
) == 0) {
421 SUNWerr(SUNW_F_DOPARSE
, SUNW_R_MAC_VERIFY_FAILURE
);
425 ret
= sunw_PKCS12_parse(p12
, passwd
, matchty
, NULL
, 0, NULL
,
429 * Error already on stack
438 * checkfile - given a file name, verify that the file exists and is
443 checkfile(char *filename
)
448 if (access(filename
, R_OK
) == -1 || stat(filename
, &sbuf
) == -1) {
449 SYSerr(SYS_F_FOPEN
, errno
);
453 if (!S_ISREG(sbuf
.st_mode
)) {
454 SUNWerr(SUNW_F_CHECKFILE
, SUNW_R_BAD_FILETYPE
);
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.
466 * pass - password to check
469 * 1 - Password is OK.
470 * 0 - Password not valid. Error stack was set - use ERR_get_error() to
474 check_password(PKCS12
*p12
, char *pass
)
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().
487 if (pass
== NULL
|| *pass
== '\0') {
488 if (PKCS12_verify_mac(p12
, NULL
, 0) == 0 &&
489 PKCS12_verify_mac(p12
, "", 0) == 0)
491 } else if (PKCS12_verify_mac(p12
, pass
, -1) == 0) {