diff options
| author | wyllys <none@none> | 2008-02-20 16:42:06 -0800 |
|---|---|---|
| committer | wyllys <none@none> | 2008-02-20 16:42:06 -0800 |
| commit | d00756ccb34596a328f8a15d1965da5412d366d0 (patch) | |
| tree | 7e086e15d7f37b4820231342edb72fb6b7e60a09 /usr/src/lib | |
| parent | f243d98a5f37cb011837c5ac9230d51aa966c997 (diff) | |
| download | illumos-gate-d00756ccb34596a328f8a15d1965da5412d366d0.tar.gz | |
PSARC 2008/037 new EKU support for pktool and kmfcfg
6648052 pktool(1) could allow certificate signing and verification
6652751 kmf_get_kmf_error_str() doesn't know about KMF_ERR_ATTR_NOT_FOUND
6654080 kmf_verify_data() should use algorithm from the cert if KMF_ALGORITHM_INDEX_ATTR is missing
6654205 kmf_find_prikey_by_cert() should be public
6654910 kmf_validate_cert() won't get over non-existent x509v3 extensions in TA
6660235 Command summary on pktool help should be localizable.
6660622 KMF needs API to determine format of raw data
Diffstat (limited to 'usr/src/lib')
| -rw-r--r-- | usr/src/lib/libkmf/ber_der/common/decode.c | 255 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/include/kmfapi.h | 10 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/include/kmfapiP.h | 115 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/include/kmfpolicy.h | 5 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/include/kmftypes.h | 55 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/certgetsetop.c | 10 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/certop.c | 173 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/csrcrlop.c | 189 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/generalop.c | 139 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/kmfoids.c | 23 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/mapfile-vers | 17 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/pem_encode.c | 26 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/policy.c | 4 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers | 3 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c | 53 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c | 51 |
16 files changed, 757 insertions, 371 deletions
diff --git a/usr/src/lib/libkmf/ber_der/common/decode.c b/usr/src/lib/libkmf/ber_der/common/decode.c index 4058ef97d5..a8666d2f2d 100644 --- a/usr/src/lib/libkmf/ber_der/common/decode.c +++ b/usr/src/lib/libkmf/ber_der/common/decode.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* @@ -144,7 +144,7 @@ kmfber_skip_tag(BerElement *ber, ber_len_t *len) return (KMFBER_DEFAULT); diff = sizeof (ber_int_t) - noctets; if (kmfber_read(ber, (char *)&netlen + diff, noctets) - != noctets) + != noctets) return (KMFBER_DEFAULT); *len = ntohl(netlen); } else { @@ -251,12 +251,12 @@ kmfber_get_stringb(BerElement *ber, char *buf, ber_len_t *len) #ifdef STR_TRANSLATION if (datalen > 0 && (ber->ber_options & KMFBER_OPT_TRANSLATE_STRINGS) - != 0 && ber->ber_decode_translate_proc != NULL) { + != 0 && ber->ber_decode_translate_proc != NULL) { transbuf = buf; ++datalen; if ((*(ber->ber_decode_translate_proc))(&transbuf, &datalen, - 0) != 0) { + 0) != 0) { return (KMFBER_DEFAULT); } if (datalen > *len) { @@ -311,7 +311,7 @@ ber_get_oid(BerElement *ber, struct berval *oid) oid->bv_len = len; if (kmfber_read(ber, oid->bv_val, oid->bv_len) != - (ber_slen_t)oid->bv_len) + (ber_slen_t)oid->bv_len) return (KMFBER_DEFAULT); return (tag); @@ -324,16 +324,18 @@ ber_get_bigint(BerElement *ber, struct berval **bv) ber_tag_t tag; if ((*bv = (struct berval *)malloc(sizeof (struct berval))) - == NULL) { + == NULL) { return (KMFBER_DEFAULT); } + (*bv)->bv_len = 0; + (*bv)->bv_val = NULL; if ((tag = kmfber_skip_tag(ber, &len)) != BER_INTEGER) { return (KMFBER_DEFAULT); } if (((*bv)->bv_val = (char *)malloc((size_t)len + 1)) - == NULL) { + == NULL) { return (KMFBER_DEFAULT); } @@ -370,7 +372,7 @@ kmfber_get_stringal(BerElement *ber, struct berval **bv) ber_tag_t tag; if ((*bv = (struct berval *)malloc(sizeof (struct berval))) - == NULL) { + == NULL) { return (KMFBER_DEFAULT); } @@ -379,7 +381,7 @@ kmfber_get_stringal(BerElement *ber, struct berval **bv) } if (((*bv)->bv_val = (char *)malloc((size_t)len + 1)) - == NULL) { + == NULL) { return (KMFBER_DEFAULT); } @@ -520,162 +522,156 @@ kmfber_scanf(BerElement *ber, const char *fmt, ...) for (rc = 0, p = (char *)fmt; *p && rc != KMFBER_DEFAULT; p++) { switch (*p) { - case 'a': /* octet string - allocate storage as needed */ + case 'a': /* octet string - allocate storage as needed */ ss = va_arg(ap, char **); rc = kmfber_get_stringa(ber, ss); break; - case 'b': /* boolean */ + case 'b': /* boolean */ i = va_arg(ap, int *); rc = kmfber_get_boolean(ber, i); break; - case 'D': /* Object ID */ + case 'D': /* Object ID */ bval = va_arg(ap, struct berval *); rc = ber_get_oid(ber, bval); break; - case 'e': /* enumerated */ - case 'i': /* int */ + case 'e': /* enumerated */ + case 'i': /* int */ b_int = va_arg(ap, ber_int_t *); rc = kmfber_get_int(ber, b_int); break; - case 'l': /* length of next item */ + case 'l': /* length of next item */ l = va_arg(ap, ber_slen_t *); rc = kmfber_peek_tag(ber, (ber_len_t *)l); break; - case 'n': /* null */ + case 'n': /* null */ rc = kmfber_get_null(ber); break; - case 's': /* octet string - in a buffer */ + case 's': /* octet string - in a buffer */ s = va_arg(ap, char *); l = va_arg(ap, ber_slen_t *); rc = kmfber_get_stringb(ber, s, (ber_len_t *)l); break; - case 'o': /* octet string in a supplied berval */ + case 'o': /* octet string in a supplied berval */ bval = va_arg(ap, struct berval *); (void) kmfber_peek_tag(ber, &bval->bv_len); rc = kmfber_get_stringa(ber, &bval->bv_val); break; - case 'I': /* variable length Integer */ + case 'I': /* variable length Integer */ /* Treat INTEGER same as an OCTET string, but ignore the tag */ bvp = va_arg(ap, struct berval **); rc = ber_get_bigint(ber, bvp); break; - case 'O': /* octet string - allocate & include length */ + case 'O': /* octet string - allocate & include length */ bvp = va_arg(ap, struct berval **); rc = kmfber_get_stringal(ber, bvp); break; - case 'B': /* bit string - allocate storage as needed */ + case 'B': /* bit string - allocate storage as needed */ ss = va_arg(ap, char **); l = va_arg(ap, ber_slen_t *); /* for length, in bits */ rc = kmfber_get_bitstringa(ber, ss, (ber_len_t *)l); break; - case 't': /* tag of next item */ + case 't': /* tag of next item */ t = va_arg(ap, ber_tag_t *); *t = kmfber_peek_tag(ber, &len); rc = (ber_int_t)(*t); break; - case 'T': /* skip tag of next item */ + case 'T': /* skip tag of next item */ t = va_arg(ap, ber_tag_t *); *t = kmfber_skip_tag(ber, &len); rc = (ber_int_t)(*t); break; - case 'v': /* sequence of strings */ + case 'v': /* sequence of strings */ sss = va_arg(ap, char ***); + if (sss == NULL) + break; *sss = NULL; j = 0; array_size = 0; for (tag = kmfber_first_element(ber, &len, &last); - (tag != KMFBER_DEFAULT && - tag != KMFBER_END_OF_SEQORSET && - rc != KMFBER_DEFAULT); - tag = kmfber_next_element(ber, &len, last)) { - if (*sss == NULL) { - /* Make room for at least 15 strings */ - *sss = (char **)malloc(16 * sizeof (char *)); - array_size = 16; - } else { - if ((size_t)(j+2) > array_size) { - /* We'v overflowed our buffer */ - *sss = (char **)realloc(*sss, - (array_size * 2) * sizeof (char *)); - array_size = array_size * 2; + (tag != KMFBER_DEFAULT && + tag != KMFBER_END_OF_SEQORSET && + rc != KMFBER_DEFAULT); + tag = kmfber_next_element(ber, &len, last)) { + if (*sss == NULL) { + /* Make room for at least 15 strings */ + *sss = (char **)malloc(16 * sizeof (char *)); + array_size = 16; + } else { + if ((size_t)(j+2) > array_size) { + /* We'v overflowed our buffer */ + *sss = (char **)realloc(*sss, + (array_size * 2) * sizeof (char *)); + array_size = array_size * 2; + } } - } - rc = kmfber_get_stringa(ber, &((*sss)[j])); - j++; + rc = kmfber_get_stringa(ber, &((*sss)[j])); + j++; } - if (rc != KMFBER_DEFAULT && - tag != KMFBER_END_OF_SEQORSET) { - rc = KMFBER_DEFAULT; + if (rc != KMFBER_DEFAULT && tag != KMFBER_END_OF_SEQORSET) { + rc = KMFBER_DEFAULT; } if (j > 0) - (*sss)[j] = NULL; + (*sss)[j] = NULL; break; - case 'V': /* sequence of strings + lengths */ + case 'V': /* sequence of strings + lengths */ bv = va_arg(ap, struct berval ***); *bv = NULL; j = 0; for (tag = kmfber_first_element(ber, &len, &last); - (tag != KMFBER_DEFAULT && - tag != KMFBER_END_OF_SEQORSET && - rc != KMFBER_DEFAULT); - tag = kmfber_next_element(ber, &len, last)) { - if (*bv == NULL) { - *bv = (struct berval **)malloc( - 2 * sizeof (struct berval *)); - } else { - *bv = (struct berval **)realloc(*bv, - (j + 2) * sizeof (struct berval *)); - } - rc = kmfber_get_stringal(ber, &((*bv)[j])); - j++; + (tag != KMFBER_DEFAULT && + tag != KMFBER_END_OF_SEQORSET && + rc != KMFBER_DEFAULT); + tag = kmfber_next_element(ber, &len, last)) { + if (*bv == NULL) { + *bv = (struct berval **)malloc( + 2 * sizeof (struct berval *)); + } else { + *bv = (struct berval **)realloc(*bv, + (j + 2) * sizeof (struct berval *)); + } + rc = kmfber_get_stringal(ber, &((*bv)[j])); + j++; } if (rc != KMFBER_DEFAULT && - tag != KMFBER_END_OF_SEQORSET) { - rc = KMFBER_DEFAULT; + tag != KMFBER_END_OF_SEQORSET) { + rc = KMFBER_DEFAULT; } if (j > 0) - (*bv)[j] = NULL; + (*bv)[j] = NULL; break; - case 'x': /* skip the next element - whatever it is */ + case 'x': /* skip the next element - whatever it is */ if ((rc = kmfber_skip_tag(ber, &len)) == KMFBER_DEFAULT) - break; + break; ber->ber_ptr += len; break; - case '{': /* begin sequence */ - case '[': /* begin set */ + case '{': /* begin sequence */ + case '[': /* begin set */ if (*(p + 1) != 'v' && *(p + 1) != 'V') - rc = kmfber_skip_tag(ber, &len); + rc = kmfber_skip_tag(ber, &len); break; - case '}': /* end sequence */ - case ']': /* end set */ + case '}': /* end sequence */ + case ']': /* end set */ break; - default: -#ifdef KMFBER_DEBUG - { - char msg[80]; - sprintf(msg, "unknown fmt %c\n", *p); - ber_err_print(msg); - } -#endif + default: rc = KMFBER_DEFAULT; break; - } + } } @@ -683,91 +679,96 @@ kmfber_scanf(BerElement *ber, const char *fmt, ...) if (rc == KMFBER_DEFAULT) { va_start(ap, fmt); for (p--; fmt < p && *fmt; fmt++) { - switch (*fmt) { + switch (*fmt) { case 'a': /* octet string - allocate storage as needed */ - ss = va_arg(ap, char **); - free(*ss); - *ss = NULL; - break; + ss = va_arg(ap, char **); + if (ss != NULL && *ss != NULL) { + free(*ss); + *ss = NULL; + } + break; case 'b': /* boolean */ - i = va_arg(ap, int *); - break; + i = va_arg(ap, int *); + break; case 'e': /* enumerated */ case 'i': /* int */ - l = va_arg(ap, ber_slen_t *); - break; + l = va_arg(ap, ber_slen_t *); + break; case 'l': /* length of next item */ - l = va_arg(ap, ber_slen_t *); - break; + l = va_arg(ap, ber_slen_t *); + break; case 'n': /* null */ - break; + break; case 's': /* octet string - in a buffer */ - s = va_arg(ap, char *); - l = va_arg(ap, ber_slen_t *); - break; + s = va_arg(ap, char *); + l = va_arg(ap, ber_slen_t *); + break; case 'o': /* octet string in a supplied berval */ - bval = va_arg(ap, struct berval *); - if (bval->bv_val) free(bval->bv_val); - (void) memset(bval, 0, sizeof (struct berval)); - break; + bval = va_arg(ap, struct berval *); + if (bval->bv_val) free(bval->bv_val); + (void) memset(bval, 0, sizeof (struct berval)); + break; case 'O': /* octet string - allocate & include length */ - bvp = va_arg(ap, struct berval **); - kmfber_bvfree(*bvp); - bvp = NULL; - break; + bvp = va_arg(ap, struct berval **); + kmfber_bvfree(*bvp); + bvp = NULL; + break; case 'B': /* bit string - allocate storage as needed */ - ss = va_arg(ap, char **); - l = va_arg(ap, ber_slen_t *); /* for length, in bits */ - if (*ss) free(*ss); - *ss = NULL; - break; + ss = va_arg(ap, char **); + l = va_arg(ap, ber_slen_t *); /* for length, in bits */ + if (ss != NULL && *ss != NULL) { + free(*ss); + *ss = NULL; + } + break; case 't': /* tag of next item */ - t = va_arg(ap, ber_tag_t *); - break; + t = va_arg(ap, ber_tag_t *); + break; case 'T': /* skip tag of next item */ - t = va_arg(ap, ber_tag_t *); - break; + t = va_arg(ap, ber_tag_t *); + break; case 'v': /* sequence of strings */ - sss = va_arg(ap, char ***); - ber_svecfree(*sss); - *sss = NULL; - break; + sss = va_arg(ap, char ***); + if (sss != NULL && *sss != NULL) { + ber_svecfree(*sss); + *sss = NULL; + } + break; case 'V': /* sequence of strings + lengths */ - bv = va_arg(ap, struct berval ***); - kmfber_bvecfree(*bv); - *bv = NULL; - break; + bv = va_arg(ap, struct berval ***); + kmfber_bvecfree(*bv); + *bv = NULL; + break; case 'x': /* skip the next element - whatever it is */ - break; + break; case '{': /* begin sequence */ case '[': /* begin set */ - break; + break; case '}': /* end sequence */ case ']': /* end set */ - break; + break; default: - break; - } + break; + } } /* for */ va_end(ap); } /* if */ - return (rc); } @@ -777,7 +778,7 @@ kmfber_bvdup(const struct berval *bv) struct berval *new; if ((new = (struct berval *)malloc(sizeof (struct berval))) - == NULL) { + == NULL) { return (NULL); } if (bv->bv_val == NULL) { @@ -785,8 +786,8 @@ kmfber_bvdup(const struct berval *bv) new->bv_len = 0; } else { if ((new->bv_val = (char *)malloc(bv->bv_len + 1)) - == NULL) { - return (NULL); + == NULL) { + return (NULL); } (void) memmove(new->bv_val, bv->bv_val, (size_t)bv->bv_len); new->bv_val[bv->bv_len] = '\0'; diff --git a/usr/src/lib/libkmf/include/kmfapi.h b/usr/src/lib/libkmf/include/kmfapi.h index 85a54175ca..4618b548ab 100644 --- a/usr/src/lib/libkmf/include/kmfapi.h +++ b/usr/src/lib/libkmf/include/kmfapi.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * @@ -87,6 +87,7 @@ extern KMF_RETURN kmf_create_cert_file(const KMF_DATA *, KMF_ENCODE_FORMAT, extern KMF_RETURN kmf_download_cert(KMF_HANDLE_T, char *, char *, int, unsigned int, char *, KMF_ENCODE_FORMAT *); +extern KMF_RETURN kmf_is_cert_data(KMF_DATA *, KMF_ENCODE_FORMAT *); extern KMF_RETURN kmf_is_cert_file(KMF_HANDLE_T, char *, KMF_ENCODE_FORMAT *); extern KMF_RETURN kmf_check_cert_date(KMF_HANDLE_T, const KMF_DATA *); @@ -128,8 +129,11 @@ extern KMF_RETURN kmf_set_csr_sig_alg(KMF_CSR_DATA *, KMF_ALGORITHM_INDEX); extern KMF_RETURN kmf_set_csr_subject_altname(KMF_CSR_DATA *, char *, int, KMF_GENERALNAMECHOICES); extern KMF_RETURN kmf_set_csr_ku(KMF_CSR_DATA *, int, uint16_t); +extern KMF_RETURN kmf_decode_csr(KMF_HANDLE_T, KMF_DATA *, KMF_CSR_DATA *); +extern KMF_RETURN kmf_verify_csr(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); extern KMF_RETURN kmf_sign_csr(KMF_HANDLE_T, const KMF_CSR_DATA *, KMF_KEY_HANDLE *, KMF_DATA *); +extern KMF_RETURN kmf_add_csr_eku(KMF_CSR_DATA *, KMF_OID *, int); /* * GetCert operations. @@ -283,6 +287,7 @@ extern KMF_RETURN kmf_pem_to_der(unsigned char *, int, unsigned char **, int *); extern char *kmf_oid_to_string(KMF_OID *); extern KMF_RETURN kmf_string_to_oid(char *, KMF_OID *); extern int kmf_compare_rdns(KMF_X509_NAME *, KMF_X509_NAME *); +extern KMF_RETURN kmf_get_data_format(KMF_DATA *, KMF_ENCODE_FORMAT *); extern KMF_RETURN kmf_get_file_format(char *, KMF_ENCODE_FORMAT *); extern uint32_t kmf_string_to_ku(char *); extern char *kmf_ku_to_string(uint32_t); @@ -292,6 +297,9 @@ extern KMF_RETURN kmf_hexstr_to_bytes(unsigned char *, unsigned char **, extern KMF_RETURN kmf_get_plugin_info(KMF_HANDLE_T, char *, KMF_KEYSTORE_TYPE *, char **); +extern KMF_OID *kmf_ekuname_to_oid(char *); +extern char *kmf_oid_to_ekuname(KMF_OID *); + #define KMF_CompareRDNs kmf_compare_rdns /* diff --git a/usr/src/lib/libkmf/include/kmfapiP.h b/usr/src/lib/libkmf/include/kmfapiP.h index 948f3acfb8..a9d9d177ce 100644 --- a/usr/src/lib/libkmf/include/kmfapiP.h +++ b/usr/src/lib/libkmf/include/kmfapiP.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _KMFAPIP_H @@ -219,62 +219,59 @@ typedef struct _kmf_handle { KMF_PLUGIN_FUNCLIST *KMF_Plugin_Initialize(); -KMF_RETURN -VerifyDataWithKey(KMF_HANDLE_T, KMF_DATA *, KMF_ALGORITHM_INDEX, KMF_DATA *, - KMF_DATA *); - -KMF_BOOL pkcs_algid_to_keytype( - KMF_ALGORITHM_INDEX, CK_KEY_TYPE *); - -KMF_RETURN PKCS_VerifyData( - KMF_HANDLE *, - KMF_ALGORITHM_INDEX, - KMF_X509_SPKI *, - KMF_DATA *, KMF_DATA *); - -KMF_RETURN PKCS_EncryptData( - KMF_HANDLE *, - KMF_ALGORITHM_INDEX, - KMF_X509_SPKI *, - KMF_DATA *, - KMF_DATA *); - -KMF_PLUGIN *FindPlugin(KMF_HANDLE_T, KMF_KEYSTORE_TYPE); - -KMF_BOOL IsEqualOid(KMF_OID *, KMF_OID *); - -KMF_RETURN copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, - KMF_X509_ALGORITHM_IDENTIFIER *srcid); - -KMF_OID *x509_algid_to_algoid(KMF_ALGORITHM_INDEX); -KMF_ALGORITHM_INDEX x509_algoid_to_algid(KMF_OID *); - -KMF_RETURN PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession, - const KMF_X509_SPKI *, CK_KEY_TYPE, CK_OBJECT_HANDLE *, - KMF_BOOL *); - -KMF_RETURN GetIDFromSPKI(KMF_X509_SPKI *, KMF_DATA *); - -KMF_RETURN kmf_set_altname(KMF_X509_EXTENSIONS *, - KMF_OID *, int, KMF_GENERALNAMECHOICES, char *); -KMF_RETURN GetSequenceContents(char *, size_t, char **, size_t *); -KMF_X509_EXTENSION *FindExtn(KMF_X509_EXTENSIONS *, KMF_OID *); -KMF_RETURN add_an_extension(KMF_X509_EXTENSIONS *exts, - KMF_X509_EXTENSION *newextn); -KMF_RETURN set_integer(KMF_DATA *, void *, int); -void free_keyidlist(KMF_OID *, int); -KMF_RETURN copy_data(KMF_DATA *, KMF_DATA *); -void Cleanup_PK11_Session(KMF_HANDLE_T handle); -void free_dp_name(KMF_CRL_DIST_POINT *); -void free_dp(KMF_CRL_DIST_POINT *); -KMF_RETURN set_key_usage_extension(KMF_X509_EXTENSIONS *, - int, uint32_t); -KMF_RETURN init_pk11(); -KMF_RETURN kmf_select_token(KMF_HANDLE_T, char *, int); - -KMF_RETURN test_attributes(int, KMF_ATTRIBUTE_TESTER *, - int, KMF_ATTRIBUTE_TESTER *, int, KMF_ATTRIBUTE *); - +extern KMF_RETURN +VerifyDataWithKey(KMF_HANDLE_T, KMF_DATA *, KMF_ALGORITHM_INDEX, + KMF_DATA *, KMF_DATA *); + +extern KMF_BOOL pkcs_algid_to_keytype( + KMF_ALGORITHM_INDEX, CK_KEY_TYPE *); + +extern KMF_RETURN PKCS_VerifyData( + KMF_HANDLE *, + KMF_ALGORITHM_INDEX, + KMF_X509_SPKI *, + KMF_DATA *, KMF_DATA *); + +extern KMF_RETURN PKCS_EncryptData( + KMF_HANDLE *, + KMF_ALGORITHM_INDEX, + KMF_X509_SPKI *, + KMF_DATA *, + KMF_DATA *); + +extern KMF_PLUGIN *FindPlugin(KMF_HANDLE_T, KMF_KEYSTORE_TYPE); + +extern KMF_BOOL IsEqualOid(KMF_OID *, KMF_OID *); + +extern KMF_RETURN copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid, + KMF_X509_ALGORITHM_IDENTIFIER *srcid); + +extern KMF_OID *x509_algid_to_algoid(KMF_ALGORITHM_INDEX); +extern KMF_ALGORITHM_INDEX x509_algoid_to_algid(KMF_OID *); + +extern KMF_RETURN PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession, + const KMF_X509_SPKI *, CK_KEY_TYPE, CK_OBJECT_HANDLE *, + KMF_BOOL *); + +extern KMF_RETURN GetIDFromSPKI(KMF_X509_SPKI *, KMF_DATA *); +extern KMF_RETURN kmf_select_token(KMF_HANDLE_T, char *, int); +extern KMF_RETURN kmf_set_altname(KMF_X509_EXTENSIONS *, + KMF_OID *, int, KMF_GENERALNAMECHOICES, char *); +extern KMF_RETURN GetSequenceContents(char *, size_t, char **, size_t *); +extern KMF_X509_EXTENSION *FindExtn(KMF_X509_EXTENSIONS *, KMF_OID *); +extern KMF_RETURN add_an_extension(KMF_X509_EXTENSIONS *exts, + KMF_X509_EXTENSION *newextn); +extern KMF_RETURN set_integer(KMF_DATA *, void *, int); +extern void free_keyidlist(KMF_OID *, int); +extern KMF_RETURN copy_data(KMF_DATA *, KMF_DATA *); +extern void Cleanup_PK11_Session(KMF_HANDLE_T handle); +extern void free_dp_name(KMF_CRL_DIST_POINT *); +extern void free_dp(KMF_CRL_DIST_POINT *); +extern KMF_RETURN set_key_usage_extension(KMF_X509_EXTENSIONS *, + int, uint32_t); +extern KMF_RETURN init_pk11(); +extern KMF_RETURN test_attributes(int, KMF_ATTRIBUTE_TESTER *, + int, KMF_ATTRIBUTE_TESTER *, int, KMF_ATTRIBUTE *); /* Indexes into the key parts array for RSA keys */ #define KMF_RSA_MODULUS (0) @@ -351,7 +348,9 @@ extern KMF_RETURN get_entrylist(conf_entrylist_t **); extern void free_entrylist(conf_entrylist_t *); extern void free_entry(conf_entry_t *); extern conf_entry_t *dup_entry(conf_entry_t *); -boolean_t is_valid_keystore_type(KMF_KEYSTORE_TYPE); +extern boolean_t is_valid_keystore_type(KMF_KEYSTORE_TYPE); +extern KMF_BOOL is_eku_present(KMF_X509EXT_EKU *, KMF_OID *); +extern KMF_RETURN parse_eku_data(const KMF_DATA *, KMF_X509EXT_EKU *); #ifdef __cplusplus } diff --git a/usr/src/lib/libkmf/include/kmfpolicy.h b/usr/src/lib/libkmf/include/kmfpolicy.h index e1cec2b56a..6a53360cee 100644 --- a/usr/src/lib/libkmf/include/kmfpolicy.h +++ b/usr/src/lib/libkmf/include/kmfpolicy.h @@ -18,7 +18,7 @@ * * CDDL HEADER END * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _KMFPOLICY_H @@ -177,9 +177,6 @@ typedef struct { extern int parsePolicyElement(xmlNodePtr, KMF_POLICY_RECORD *); -extern char *kmf_oid_to_eku_string(KMF_OID *); -extern KMF_OID *kmf_ekuname_to_oid(char *); - extern KMF_RETURN kmf_get_policy(char *, char *, KMF_POLICY_RECORD *); extern KMF_RETURN kmf_add_policy_to_db(KMF_POLICY_RECORD *, char *, boolean_t); extern KMF_RETURN kmf_delete_policy_from_db(char *, char *); diff --git a/usr/src/lib/libkmf/include/kmftypes.h b/usr/src/lib/libkmf/include/kmftypes.h index cb970800db..d6a6f04733 100644 --- a/usr/src/lib/libkmf/include/kmftypes.h +++ b/usr/src/lib/libkmf/include/kmftypes.h @@ -2,7 +2,7 @@ * Copyright (c) 1995-2000 Intel Corporation. All rights reserved. */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -229,7 +229,9 @@ typedef enum { GENNAME_EDIPARTYNAME, GENNAME_URI, GENNAME_IPADDRESS, - GENNAME_REGISTEREDID + GENNAME_REGISTEREDID, + GENNAME_KRB5PRINC, + GENNAME_SCLOGON_UPN } KMF_GENERALNAMECHOICES; /* @@ -956,8 +958,45 @@ typedef struct { #define OID_PKIX_AD_CAISSUERS_LENGTH (OID_PKIX_AD_LENGTH + 1) /* end PKIX part1 */ -#define OID_APPL_TCP_PROTO 43, 6, 1, 2, 1, 27, 4 -#define OID_APPL_TCP_PROTO_LENGTH 8 + +/* + * From RFC4556 (PKINIT) + * + * pkinit = { iso(1) identified-organization(3) dod(6) internet(1) + * security(5) kerberosv5(2) pkinit(3) } + */ +#define OID_KRB5_PKINIT 43, 6, 1, 5, 2, 3 +#define OID_KRB5_PKINIT_LENGTH 6 + +#define OID_KRB5_PKINIT_KPCLIENTAUTH OID_KRB5_PKINIT, 4 +#define OID_KRB5_PKINIT_KPCLIENTAUTH_LENGTH (OID_KRB5_PKINIT_LENGTH + 1) + +#define OID_KRB5_PKINIT_KPKDC OID_KRB5_PKINIT, 5 +#define OID_KRB5_PKINIT_KPKDC_LENGTH (OID_KRB5_PKINIT_LENGTH + 1) + +#define OID_KRB5_SAN 43, 6, 1, 5, 2, 2 +#define OID_KRB5_SAN_LENGTH 6 + +/* + * Microsoft OIDs: + * id-ms-san-sc-logon-upn = + * {iso(1) identified-organization(3) dod(6) internet(1) private(4) + * enterprise(1) microsoft(311) 20 2 3} + * + * id-ms-kp-sc-logon = + * {iso(1) identified-organization(3) dod(6) internet(1) private(4) + * enterprise(1) microsoft(311) 20 2 2} + */ +#define OID_MS 43, 6, 1, 4, 1, 130, 55 +#define OID_MS_LENGTH 7 +#define OID_MS_KP_SC_LOGON OID_MS, 20, 2, 2 +#define OID_MS_KP_SC_LOGON_LENGTH (OID_MS_LENGTH + 3) + +#define OID_MS_KP_SC_LOGON_UPN OID_MS, 20, 2, 3 +#define OID_MS_KP_SC_LOGON_UPN_LENGTH (OID_MS_LENGTH + 3) + +#define OID_APPL_TCP_PROTO 43, 6, 1, 2, 1, 27, 4 +#define OID_APPL_TCP_PROTO_LENGTH 8 #define OID_DAP OID_DS, 3, 1 #define OID_DAP_LENGTH (OID_DS_LENGTH + 2) @@ -1127,6 +1166,14 @@ KMFOID_OIW_DSAWithSHA1, KMFOID_X9CM_DSA, KMFOID_X9CM_DSAWithSHA1; +/* For PKINIT support */ +extern const KMF_OID +KMFOID_PKINIT_san, +KMFOID_PKINIT_ClientAuth, +KMFOID_PKINIT_Kdc, +KMFOID_MS_KP_SCLogon, +KMFOID_MS_KP_SCLogon_UPN; + /* * KMF Certificate validation codes. These may be masked together. */ diff --git a/usr/src/lib/libkmf/libkmf/common/certgetsetop.c b/usr/src/lib/libkmf/libkmf/common/certgetsetop.c index 1dcdb8aaa8..4aa65fbebb 100644 --- a/usr/src/lib/libkmf/libkmf/common/certgetsetop.c +++ b/usr/src/lib/libkmf/libkmf/common/certgetsetop.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -289,8 +289,8 @@ end: return (ret); } -static KMF_BOOL -isEKUPresent(KMF_X509EXT_EKU *ekuptr, KMF_OID *ekuoid) +KMF_BOOL +is_eku_present(KMF_X509EXT_EKU *ekuptr, KMF_OID *ekuoid) { int i; @@ -304,7 +304,7 @@ isEKUPresent(KMF_X509EXT_EKU *ekuptr, KMF_OID *ekuoid) return (0); } -static KMF_RETURN +KMF_RETURN parse_eku_data(const KMF_DATA *asn1data, KMF_X509EXT_EKU *ekuptr) { KMF_RETURN ret = KMF_OK; @@ -2097,7 +2097,7 @@ kmf_add_cert_eku(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID, */ ret = parse_eku_data(&foundextn->BERvalue, &ekudata); if (ret == KMF_OK) { - if (isEKUPresent(&ekudata, ekuOID)) { + if (is_eku_present(&ekudata, ekuOID)) { goto out; } } diff --git a/usr/src/lib/libkmf/libkmf/common/certop.c b/usr/src/lib/libkmf/libkmf/common/certop.c index 3ad7c4b757..7390ef1dd0 100644 --- a/usr/src/lib/libkmf/libkmf/common/certop.c +++ b/usr/src/lib/libkmf/libkmf/common/certop.c @@ -52,7 +52,6 @@ verify_cert_with_key(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *); static KMF_RETURN verify_cert_with_cert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *); - static KMF_RETURN get_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg) { @@ -180,7 +179,6 @@ check_key_usage(void *handle, */ return (ret); - switch (purpose) { case KMF_KU_SIGN_CERT: /* @@ -409,6 +407,7 @@ kmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) KMF_DATA unsignedCert = {NULL, 0}; KMF_KEY_HANDLE sign_key, *sign_key_ptr; int freethekey = 0; + KMF_POLICY_RECORD *policy; KMF_X509_CERTIFICATE *x509cert; KMF_ATTRIBUTE_TESTER required_attrs[] = { {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, @@ -436,7 +435,10 @@ kmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) return (KMF_ERR_BAD_PARAMETER); if (signer_cert != NULL) { + policy = handle->policy; ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_CERT); + if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) + ret = KMF_OK; if (ret != KMF_OK) return (ret); @@ -496,6 +498,33 @@ out: return (ret); } +static KMF_RETURN +get_sigalg_from_cert(KMF_DATA *signer_cert, KMF_ALGORITHM_INDEX *AlgId) +{ + KMF_RETURN ret = KMF_OK; + KMF_X509_CERTIFICATE *x509_cert = NULL; + KMF_OID *oid; + + *AlgId = KMF_ALGID_NONE; + + /* if no OID and no AlgID, use the signer cert */ + ret = DerDecodeSignedCertificate(signer_cert, &x509_cert); + if (ret != KMF_OK) + return (ret); + + oid = CERT_ALG_OID(x509_cert); + *AlgId = x509_algoid_to_algid(oid); + + if (*AlgId == KMF_ALGID_NONE) + ret = KMF_ERR_BAD_PARAMETER; + + if (x509_cert != NULL) { + kmf_free_signed_cert(x509_cert); + free(x509_cert); + } + return (ret); +} + /* * Name: kmf_sign_data * @@ -515,10 +544,10 @@ kmf_sign_data(KMF_HANDLE_T handle, int numattr, KMF_DATA *tbs_data = NULL; /* to be signed data */ KMF_DATA *output = NULL; KMF_KEY_HANDLE sign_key, *sign_key_ptr; - KMF_X509_CERTIFICATE *x509_cert = NULL; KMF_ALGORITHM_INDEX AlgId; KMF_DATA signature = {0, NULL}; KMF_OID *oid; + KMF_POLICY_RECORD *policy; KMF_ATTRIBUTE_TESTER required_attrs[] = { {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, @@ -558,7 +587,8 @@ kmf_sign_data(KMF_HANDLE_T handle, int numattr, * Signing generic data does not require the * KeyUsage extension. */ - if (ret == KMF_ERR_EXTENSION_NOT_FOUND) + policy = handle->policy; + if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) ret = KMF_OK; if (ret != KMF_OK) return (ret); @@ -612,17 +642,12 @@ kmf_sign_data(KMF_HANDLE_T handle, int numattr, ret = KMF_ERR_BAD_PARAMETER; goto cleanup; } else if (oid == NULL && ret != KMF_OK) { - /* if no OID and No AlgID, use the signer cert */ - ret = DerDecodeSignedCertificate(signer_cert, &x509_cert); + ret = get_sigalg_from_cert(signer_cert, &AlgId); if (ret != KMF_OK) goto cleanup; + else + oid = x509_algid_to_algoid(AlgId); - oid = CERT_ALG_OID(x509_cert); - AlgId = x509_algoid_to_algid(oid); - if (AlgId == KMF_ALGID_NONE) { - ret = KMF_ERR_BAD_PARAMETER; - goto cleanup; - } } else if (oid == NULL && ret == KMF_OK) { /* AlgID was given by caller, convert it to OID */ oid = x509_algid_to_algoid(AlgId); @@ -665,10 +690,6 @@ cleanup: if (signer_cert != NULL && sign_key_ptr != NULL) kmf_free_kmf_key(handle, sign_key_ptr); - if (x509_cert != NULL) { - kmf_free_signed_cert(x509_cert); - free(x509_cert); - } return (ret); } @@ -708,6 +729,7 @@ kmf_verify_data(KMF_HANDLE_T handle, KMF_DATA *insig; KMF_DATA *signer_cert; KMF_X509_SPKI spki; + KMF_POLICY_RECORD *policy; KMF_ATTRIBUTE_TESTER required_attrs[] = { {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, @@ -747,7 +769,9 @@ kmf_verify_data(KMF_HANDLE_T handle, len = sizeof (sigAlg); ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, num_args, &sigAlg, &len); - if (ret != KMF_OK) + + /* We only need the algorithm index if we don't have a signer cert. */ + if (ret != KMF_OK && signer_cert == NULL) return (ret); indata = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, num_args); @@ -760,7 +784,10 @@ kmf_verify_data(KMF_HANDLE_T handle, /* If the caller passed a signer cert instead of a key use it. */ if (signer_cert != NULL) { + policy = handle->policy; ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA); + if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) + ret = KMF_OK; if (ret != KMF_OK) return (ret); @@ -977,6 +1004,7 @@ kmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) KMF_DATA *cert; KMF_DATA *plaintext; KMF_DATA *ciphertext; + KMF_POLICY_RECORD *policy; KMF_ATTRIBUTE_TESTER required_attrs[] = { {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, @@ -1009,8 +1037,9 @@ kmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) return (KMF_ERR_BAD_PARAMETER); /* check the keyUsage of the certificate */ + policy = handle->policy; ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA); - if (ret == KMF_ERR_EXTENSION_NOT_FOUND) + if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) ret = KMF_OK; if (ret != KMF_OK) return (ret); @@ -1066,6 +1095,7 @@ kmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) KMF_DATA *ciphertext = NULL; KMF_DATA *plaintext = NULL; KMF_KEY_HANDLE prikey; + KMF_POLICY_RECORD *policy; KMF_ATTRIBUTE_TESTER required_attrs[] = { {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}, @@ -1094,8 +1124,9 @@ kmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) return (KMF_ERR_BAD_PARAMETER); /* check the keyUsage of the certificate */ + policy = handle->policy; ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA); - if (ret == KMF_ERR_EXTENSION_NOT_FOUND) + if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) ret = KMF_OK; if (ret != KMF_OK) return (ret); @@ -2248,8 +2279,11 @@ find_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype, kmf_free_dn(&ta_subjectDN); /* Make sure the TA cert has the correct extensions */ - if (ret == KMF_OK) + if (ret == KMF_OK) { ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT); + if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) + ret = KMF_OK; + } out: if (ta_retrCert.certificate.Data) kmf_free_kmf_cert(handle, &ta_retrCert); @@ -2420,10 +2454,6 @@ kmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) goto out; } - ret = check_key_usage(handle, &ta_cert, KMF_KU_SIGN_CERT); - if (ret != KMF_OK) - goto out; - ret = verify_cert_with_cert(handle, pcert, &ta_cert); } if (ret != KMF_OK) { @@ -2545,39 +2575,82 @@ cleanup: return (rv); } +/* + * kmf_is_cert_data + * + * Determine if a KMF_DATA buffer contains an encoded X.509 certificate. + * + * Return: + * KMF_OK if it is a certificate + * KMF_ERR_ENCODING (or other error) if not. + */ +KMF_RETURN +kmf_is_cert_data(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt) +{ + KMF_RETURN rv = KMF_OK; + KMF_X509_CERTIFICATE *x509 = NULL; + KMF_DATA oldpem = {0, NULL}; + uchar_t *d = NULL; + int len = 0; + + if (data == NULL || fmt == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = kmf_get_data_format(data, fmt); + if (rv != KMF_OK) + return (rv); + switch (*fmt) { + case KMF_FORMAT_ASN1: + rv = DerDecodeSignedCertificate(data, &x509); + break; + case KMF_FORMAT_PEM: + /* Convert to ASN.1 DER first */ + rv = kmf_pem_to_der(data->Data, data->Length, + &d, &len); + if (rv != KMF_OK) + return (rv); + oldpem.Data = d; + oldpem.Length = len; + rv = DerDecodeSignedCertificate(&oldpem, &x509); + kmf_free_data(&oldpem); + break; + case KMF_FORMAT_PKCS12: + case KMF_FORMAT_UNDEF: + default: + return (KMF_ERR_ENCODING); + } + + if (x509 != NULL) { + kmf_free_signed_cert(x509); + free(x509); + } + return (rv); +} + KMF_RETURN kmf_is_cert_file(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat) { - KMF_PLUGIN *plugin; - KMF_RETURN (*IsCertFileFn)(void *, char *, KMF_ENCODE_FORMAT *); - KMF_RETURN ret; + KMF_DATA filedata; CLEAR_ERROR(handle, ret); if (ret != KMF_OK) return (ret); - if (filename == NULL || pformat == NULL) { + if (filename == NULL || pformat == NULL) return (KMF_ERR_BAD_PARAMETER); - } - /* - * This framework function is actually implemented in the openssl - * plugin library, so we find the function address and call it. - */ - plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); - if (plugin == NULL || plugin->dldesc == NULL) { - return (KMF_ERR_PLUGIN_NOTFOUND); - } + ret = kmf_read_input_file(handle, filename, &filedata); + if (ret != KMF_OK) + return (ret); - IsCertFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, - "OpenSSL_IsCertFile"); - if (IsCertFileFn == NULL) { - return (KMF_ERR_FUNCTION_NOT_FOUND); - } + ret = kmf_is_cert_data(&filedata, pformat); + if (ret == KMF_ERR_BAD_CERT_FORMAT) + ret = KMF_ERR_BAD_CERTFILE; - return (IsCertFileFn(handle, filename, pformat)); + kmf_free_data(&filedata); + return (ret); } /* @@ -3005,8 +3078,10 @@ verify_cert_with_cert(KMF_HANDLE_T handle, KMF_DATA signed_data = {0, NULL}; KMF_DATA signature; KMF_ALGORITHM_INDEX algid; + KMF_POLICY_RECORD *policy; - if (!CertToBeVerifiedData || + if (handle == NULL || + !CertToBeVerifiedData || !CertToBeVerifiedData->Data || !CertToBeVerifiedData->Length) return (KMF_ERR_BAD_PARAMETER); @@ -3016,8 +3091,12 @@ verify_cert_with_cert(KMF_HANDLE_T handle, !SignerCertData->Length) return (KMF_ERR_BAD_PARAMETER); + policy = handle->policy; + /* Make sure the signer has proper key usage bits */ ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT); + if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0) + ret = KMF_OK; if (ret != KMF_OK) return (ret); @@ -3116,15 +3195,9 @@ KMF_VerifyCertWithCert(KMF_HANDLE_T handle, const KMF_DATA *CertToBeVerified, const KMF_DATA *SignerCert) { - KMF_RETURN ret; if (CertToBeVerified == NULL || SignerCert == NULL) return (KMF_ERR_BAD_PARAMETER); - /* check the keyUsage of signer's certificate */ - ret = check_key_usage(handle, SignerCert, KMF_KU_SIGN_CERT); - if (ret != KMF_OK) - return (ret); - return (verify_cert_with_cert(handle, CertToBeVerified, SignerCert)); } diff --git a/usr/src/lib/libkmf/libkmf/common/csrcrlop.c b/usr/src/lib/libkmf/libkmf/common/csrcrlop.c index b0af23b27c..2d72a57b4b 100644 --- a/usr/src/lib/libkmf/libkmf/common/csrcrlop.c +++ b/usr/src/lib/libkmf/libkmf/common/csrcrlop.c @@ -18,7 +18,7 @@ * * CDDL HEADER END * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -255,8 +255,112 @@ kmf_set_csr_ku(KMF_CSR_DATA *CSRData, return (ret); } +KMF_RETURN +kmf_add_csr_eku(KMF_CSR_DATA *CSRData, KMF_OID *ekuOID, + int critical) +{ + KMF_RETURN ret = KMF_OK; + KMF_X509_EXTENSION *foundextn; + KMF_X509_EXTENSION newextn; + BerElement *asn1 = NULL; + BerValue *extdata = NULL; + char *olddata = NULL; + size_t oldsize = 0; + KMF_X509EXT_EKU ekudata; + + if (CSRData == NULL || ekuOID == NULL) + return (KMF_ERR_BAD_PARAMETER); + + (void) memset(&ekudata, 0, sizeof (KMF_X509EXT_EKU)); + (void) memset(&newextn, 0, sizeof (newextn)); + + foundextn = FindExtn(&CSRData->csr.extensions, + (KMF_OID *)&KMFOID_ExtendedKeyUsage); + if (foundextn != NULL) { + ret = GetSequenceContents((char *)foundextn->BERvalue.Data, + foundextn->BERvalue.Length, &olddata, &oldsize); + if (ret != KMF_OK) + goto out; + + /* + * If the EKU is already in the cert, then just return OK. + */ + ret = parse_eku_data(&foundextn->BERvalue, &ekudata); + if (ret == KMF_OK) { + if (is_eku_present(&ekudata, ekuOID)) { + goto out; + } + } + } + if ((asn1 = kmfder_alloc()) == NULL) + return (KMF_ERR_MEMORY); + + if (kmfber_printf(asn1, "{") == -1) { + ret = KMF_ERR_ENCODING; + goto out; + } + + /* Write the old extension data first */ + if (olddata != NULL && oldsize > 0) { + if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { + ret = KMF_ERR_ENCODING; + goto out; + } + } + + /* Append this EKU OID and close the sequence */ + if (kmfber_printf(asn1, "D}", ekuOID) == -1) { + ret = KMF_ERR_ENCODING; + goto out; + } + + if (kmfber_flatten(asn1, &extdata) == -1) { + ret = KMF_ERR_ENCODING; + goto out; + } + + /* + * If we are just adding to an existing list of EKU OIDs, + * just replace the BER data associated with the found extension. + */ + if (foundextn != NULL) { + free(foundextn->BERvalue.Data); + foundextn->critical = critical; + foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; + foundextn->BERvalue.Length = extdata->bv_len; + } else { + ret = copy_data(&newextn.extnId, + (KMF_DATA *)&KMFOID_ExtendedKeyUsage); + if (ret != KMF_OK) + goto out; + newextn.critical = critical; + newextn.format = KMF_X509_DATAFORMAT_ENCODED; + newextn.BERvalue.Data = (uchar_t *)extdata->bv_val; + newextn.BERvalue.Length = extdata->bv_len; + ret = kmf_set_csr_extn(CSRData, &newextn); + if (ret != KMF_OK) + free(newextn.BERvalue.Data); + } + +out: + kmf_free_eku(&ekudata); + if (extdata != NULL) + free(extdata); + + if (olddata != NULL) + free(olddata); + + if (asn1 != NULL) + kmfber_free(asn1, 1); + + if (ret != KMF_OK) + kmf_free_data(&newextn.extnId); + + return (ret); +} + static KMF_RETURN -SignCsr(KMF_HANDLE_T handle, +sign_csr(KMF_HANDLE_T handle, const KMF_DATA *SubjectCsr, KMF_KEY_HANDLE *Signkey, KMF_X509_ALGORITHM_IDENTIFIER *algo, @@ -376,7 +480,7 @@ kmf_sign_csr(KMF_HANDLE_T handle, err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata); if (err == KMF_OK) { - err = SignCsr(handle, &csrdata, Signkey, + err = sign_csr(handle, &csrdata, Signkey, (KMF_X509_ALGORITHM_IDENTIFIER *) &tbsCsr->signature.algorithmIdentifier, SignedCsr); @@ -389,6 +493,85 @@ kmf_sign_csr(KMF_HANDLE_T handle, return (err); } +/* + * kmf_decode_csr + * + * Description: + * This function decodes raw CSR data and fills in the KMF_CSR_DATA + * record. + * + * Inputs: + * KMF_HANDLE_T handle + * KMF_DATA *rawcsr + * KMF_CSR_DATA *csrdata; + */ +KMF_RETURN +kmf_decode_csr(KMF_HANDLE_T handle, KMF_DATA *rawcsr, KMF_CSR_DATA *csrdata) +{ + KMF_RETURN rv; + KMF_CSR_DATA *cdata = NULL; + + if (handle == NULL || rawcsr == NULL || csrdata == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = DerDecodeSignedCsr(rawcsr, &cdata); + if (rv != KMF_OK) + return (rv); + + (void) memcpy(csrdata, cdata, sizeof (KMF_CSR_DATA)); + + free(cdata); + return (rv); +} + +KMF_RETURN +kmf_verify_csr(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN rv = KMF_OK; + KMF_CSR_DATA *csrdata = NULL; + KMF_ALGORITHM_INDEX algid; + KMF_X509_ALGORITHM_IDENTIFIER *x509alg; + KMF_DATA rawcsr; + + KMF_ATTRIBUTE_TESTER required_attrs[] = { + {KMF_CSR_DATA_ATTR, FALSE, sizeof (KMF_CSR_DATA), + sizeof (KMF_CSR_DATA)}, + }; + + int num_req_attrs = sizeof (required_attrs) / + sizeof (KMF_ATTRIBUTE_TESTER); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + CLEAR_ERROR(handle, rv); + + rv = test_attributes(num_req_attrs, required_attrs, + 0, NULL, numattr, attrlist); + if (rv != KMF_OK) + return (rv); + + csrdata = kmf_get_attr_ptr(KMF_CSR_DATA_ATTR, attrlist, numattr); + if (csrdata == NULL) + return (KMF_ERR_BAD_PARAMETER); + + rv = DerEncodeTbsCsr(&csrdata->csr, &rawcsr); + if (rv != KMF_OK) + return (rv); + + x509alg = &csrdata->signature.algorithmIdentifier; + algid = x509_algoid_to_algid(&x509alg->algorithm); + + rv = PKCS_VerifyData(handle, algid, + &csrdata->csr.subjectPublicKeyInfo, + &rawcsr, + &csrdata->signature.encrypted); + + kmf_free_data(&rawcsr); + return (rv); +} + static KMF_RETURN setup_crl_call(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist, KMF_PLUGIN **plugin) diff --git a/usr/src/lib/libkmf/libkmf/common/generalop.c b/usr/src/lib/libkmf/libkmf/common/generalop.c index e5a19df4b5..b87d23ed89 100644 --- a/usr/src/lib/libkmf/libkmf/common/generalop.c +++ b/usr/src/lib/libkmf/libkmf/common/generalop.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * */ @@ -137,7 +137,9 @@ static kmf_error_map kmf_errcodes[] = { {KMF_KEYSTORE_ALREADY_INITIALIZED, "KMF_KEYSTORE_ALREADY_INITIALIZED"}, {KMF_ERR_SENSITIVE_KEY, "KMF_ERR_SENSITIVE_KEY"}, {KMF_ERR_UNEXTRACTABLE_KEY, "KMF_ERR_UNEXTRACTABLE_KEY"}, - {KMF_ERR_KEY_MISMATCH, "KMF_ERR_KEY_MISMATCH"} + {KMF_ERR_KEY_MISMATCH, "KMF_ERR_KEY_MISMATCH"}, + {KMF_ERR_ATTR_NOT_FOUND, "KMF_ERR_ATTR_NOT_FOUND"}, + {KMF_ERR_KMF_CONF, "KMF_ERR_KMF_CONF"} }; typedef struct { @@ -820,10 +822,16 @@ static boolean_t check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt) { char *p; + int i; if (buf == NULL) return (FALSE); + for (i = 0; i < 8 && isascii(buf[i]); i++) + /* loop to make sure this is ascii */; + if (i != 8) + return (FALSE); + if (memcmp(buf, "Bag Attr", 8) == 0) { *fmt = KMF_FORMAT_PEM_KEYPAIR; return (TRUE); @@ -834,8 +842,11 @@ check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt) while (p != NULL) { if (strstr(p, "-----BEGIN") != NULL) { *fmt = KMF_FORMAT_PEM; + /* Restore the buffer */ + buf[strlen(p)] = '\n'; return (TRUE); } + buf[strlen(p)] = '\n'; p = strtok(NULL, "\n"); } return (FALSE); @@ -932,11 +943,28 @@ check_for_pkcs12(uchar_t *buf, int buf_len) } KMF_RETURN +kmf_get_data_format(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt) +{ + uchar_t *buf = data->Data; + + if (check_for_pkcs12(buf, data->Length) == TRUE) { + *fmt = KMF_FORMAT_PKCS12; + } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { + /* It is most likely a generic ASN.1 encoded file */ + *fmt = KMF_FORMAT_ASN1; + } else if (check_for_pem(buf, fmt) != TRUE) { + /* Cannot determine this file format */ + *fmt = KMF_FORMAT_UNDEF; + return (KMF_ERR_ENCODING); + } + return (KMF_OK); +} + +KMF_RETURN kmf_get_file_format(char *filename, KMF_ENCODE_FORMAT *fmt) { KMF_RETURN ret = KMF_OK; KMF_DATA filebuf = {NULL, 0}; - uchar_t *buf; if (filename == NULL || !strlen(filename) || fmt == NULL) return (KMF_ERR_BAD_PARAMETER); @@ -951,20 +979,7 @@ kmf_get_file_format(char *filename, KMF_ENCODE_FORMAT *fmt) goto end; } - buf = filebuf.Data; - if (check_for_pkcs12(buf, filebuf.Length) == TRUE) { - *fmt = KMF_FORMAT_PKCS12; - } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { - /* It is most likely a generic ASN.1 encoded file */ - *fmt = KMF_FORMAT_ASN1; - } else if (check_for_pem(buf, fmt) == TRUE) { - goto end; - } else { - /* Cannot determine this file format */ - *fmt = 0; - ret = KMF_ERR_ENCODING; - } - + ret = kmf_get_data_format(&filebuf, fmt); end: kmf_free_data(&filebuf); return (ret); @@ -1676,6 +1691,88 @@ encode_ipaddr(char *name, KMF_DATA *derdata) } static KMF_RETURN +encode_krb5(char *name, KMF_DATA *derdata) +{ + KMF_RETURN rv = KMF_OK; + char *at, *realm; + BerElement *asn1 = NULL; + BerValue *extdata = NULL; + + at = strchr(name, '@'); + if (at == NULL) + return (KMF_ERR_ENCODING); + + realm = at+1; + *at = 0; + + if ((asn1 = kmfder_alloc()) == NULL) + return (KMF_ERR_MEMORY); + + if (kmfber_printf(asn1, "{D{", &KMFOID_PKINIT_san) == -1) + goto cleanup; + + if (kmfber_printf(asn1, "l", strlen(realm)) == -1) + goto cleanup; + if (kmfber_write(asn1, realm, strlen(realm), 0) != strlen(realm)) + goto cleanup; + if (kmfber_printf(asn1, "l", strlen(name)) == -1) + goto cleanup; + if (kmfber_write(asn1, name, strlen(name), 0) != strlen(name)) + goto cleanup; + if (kmfber_printf(asn1, "}}") == -1) + goto cleanup; + + if (kmfber_flatten(asn1, &extdata) == -1) { + rv = KMF_ERR_ENCODING; + goto cleanup; + } + + derdata->Data = (uchar_t *)extdata->bv_val; + derdata->Length = extdata->bv_len; + + free(extdata); +cleanup: + if (asn1 != NULL) + kmfber_free(asn1, 1); + + if (*at == 0) + *at = '@'; + + return (rv); +} + +static KMF_RETURN +encode_sclogon(char *name, KMF_DATA *derdata) +{ + KMF_RETURN rv = KMF_OK; + BerElement *asn1 = NULL; + BerValue *extdata = NULL; + + if ((asn1 = kmfder_alloc()) == NULL) + return (KMF_ERR_MEMORY); + + /* The name is encoded as a KerberosString (IA5STRING) */ + if (kmfber_printf(asn1, "{Ds}", + &KMFOID_MS_KP_SCLogon, name) == -1) + goto cleanup; + + if (kmfber_flatten(asn1, &extdata) == -1) { + rv = KMF_ERR_ENCODING; + goto cleanup; + } + + derdata->Data = (uchar_t *)extdata->bv_val; + derdata->Length = extdata->bv_len; + + free(extdata); +cleanup: + if (asn1 != NULL) + kmfber_free(asn1, 1); + + return (rv); +} + +static KMF_RETURN verify_uri_format(char *uristring) { KMF_RETURN ret = KMF_OK; @@ -1765,6 +1862,14 @@ encode_altname(char *namedata, (void) kmf_free_dn(&dnname); tagval = (0xA0 | nametype); break; + case GENNAME_KRB5PRINC: + tagval = (0x80 | GENNAME_OTHERNAME); + ret = encode_krb5(namedata, encodedname); + break; + case GENNAME_SCLOGON_UPN: + tagval = (0x80 | GENNAME_OTHERNAME); + ret = encode_sclogon(namedata, encodedname); + break; default: /* unsupported */ return (KMF_ERR_BAD_PARAMETER); diff --git a/usr/src/lib/libkmf/libkmf/common/kmfoids.c b/usr/src/lib/libkmf/libkmf/common/kmfoids.c index 75b5bad7e0..c79570de8b 100644 --- a/usr/src/lib/libkmf/libkmf/common/kmfoids.c +++ b/usr/src/lib/libkmf/libkmf/common/kmfoids.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* @@ -379,3 +379,24 @@ KMFOID_OIW_DSAWithSHA1 = {OID_OIW_ALGORITHM_LENGTH+1, KMFOID_X9CM_DSA = {OID_X9CM_X9ALGORITHM_LENGTH+1, OID_X9CM_DSA}, KMFOID_X9CM_DSAWithSHA1 = {OID_X9CM_X9ALGORITHM_LENGTH+1, OID_X9CM_DSAWithSHA1}; + +/* + * New for PKINIT support. + */ +static uint8_t +OID_pkinit_san[] = { OID_KRB5_SAN }, +OID_pkinit_san_upn[] = { OID_MS_KP_SC_LOGON_UPN }, +OID_pkinit_kp_clientauth[] = { OID_KRB5_PKINIT_KPCLIENTAUTH }, +OID_pkinit_kp_kdc[] = { OID_KRB5_PKINIT_KPKDC }, +OID_pkinit_kp_sc_logon[] = { OID_MS_KP_SC_LOGON }; + +const KMF_OID +KMFOID_PKINIT_san = {OID_KRB5_SAN_LENGTH, OID_pkinit_san }, +KMFOID_PKINIT_ClientAuth = {OID_KRB5_PKINIT_KPCLIENTAUTH_LENGTH, + OID_pkinit_kp_clientauth}, +KMFOID_PKINIT_Kdc = {OID_KRB5_PKINIT_KPKDC_LENGTH, + OID_pkinit_kp_kdc}, +KMFOID_MS_KP_SCLogon = {OID_MS_KP_SC_LOGON_LENGTH, + OID_pkinit_kp_sc_logon}, +KMFOID_MS_KP_SCLogon_UPN = {OID_MS_KP_SC_LOGON_UPN_LENGTH, + OID_pkinit_san_upn}; diff --git a/usr/src/lib/libkmf/libkmf/common/mapfile-vers b/usr/src/lib/libkmf/libkmf/common/mapfile-vers index 4b658709c5..9fb921cdb7 100644 --- a/usr/src/lib/libkmf/libkmf/common/mapfile-vers +++ b/usr/src/lib/libkmf/libkmf/common/mapfile-vers @@ -18,7 +18,7 @@ # # CDDL HEADER END # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -87,6 +87,8 @@ SUNW_1.1 { KMFOID_MD5WithRSA; KMFOID_Member; KMFOID_MessageDigest; + KMFOID_MS_KP_SCLogon; + KMFOID_MS_KP_SCLogon_UPN; KMFOID_Name; KMFOID_NameConstraints; KMFOID_OIW_DSAWithSHA1; @@ -94,6 +96,9 @@ SUNW_1.1 { KMFOID_OrganizationName; KMFOID_OrganizationalUnitName; KMFOID_Owner; + KMFOID_PKINIT_ClientAuth; + KMFOID_PKINIT_Kdc; + KMFOID_PKINIT_san; KMFOID_PKIX_KP_ClientAuth; KMFOID_PKIX_KP_CodeSigning; KMFOID_PKIX_KP_EmailProtection; @@ -152,6 +157,7 @@ SUNW_1.1 { KMFOID_domainComponent; KMFOID_userid; kmf_add_cert_eku; + kmf_add_csr_eku; kmf_add_policy_to_db; kmf_build_pk12; kmf_check_cert_date; @@ -163,6 +169,7 @@ SUNW_1.1 { kmf_create_keypair; kmf_create_ocsp_request; kmf_create_sym_key; + kmf_decode_csr; kmf_decrypt; kmf_delete_cert_from_keystore; kmf_delete_crl; @@ -182,6 +189,7 @@ SUNW_1.1 { kmf_find_cert_in_crl; kmf_find_crl; kmf_find_key; + kmf_find_prikey_by_cert; kmf_free_algoid; kmf_free_bigint; kmf_free_crl_dist_pts; @@ -225,6 +233,7 @@ SUNW_1.1 { kmf_get_cert_subject_str; kmf_get_cert_validity; kmf_get_cert_version_str; + kmf_get_data_format; kmf_get_encoded_ocsp_response; kmf_get_file_format; kmf_get_kmf_error_str; @@ -241,16 +250,16 @@ SUNW_1.1 { kmf_import_cert; kmf_import_objects; kmf_initialize; + kmf_is_cert_data; kmf_is_cert_file; kmf_is_crl_file; kmf_ku_to_string; kmf_list_crl; - kmf_oid_to_eku_string; + kmf_oid_to_ekuname; kmf_oid_to_string; kmf_pem_to_der; kmf_pk11_token_lookup; kmf_read_input_file; - kmf_select_token; kmf_set_attr; kmf_set_attr_at_index; kmf_set_cert_basic_constraint; @@ -284,6 +293,7 @@ SUNW_1.1 { kmf_validate_cert; kmf_verify_cert; kmf_verify_crl_file; + kmf_verify_csr; kmf_verify_data; kmf_verify_policy; local: @@ -323,6 +333,7 @@ SUNWprivate_1.1 { free_entry; free_entrylist; get_entrylist; + kmf_select_token; parsePolicyElement; PKCS_AcquirePublicKeyHandle; PKCS_GetDefaultSignatureMode; diff --git a/usr/src/lib/libkmf/libkmf/common/pem_encode.c b/usr/src/lib/libkmf/libkmf/common/pem_encode.c index c80db6bdc6..40157c82e4 100644 --- a/usr/src/lib/libkmf/libkmf/common/pem_encode.c +++ b/usr/src/lib/libkmf/libkmf/common/pem_encode.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -467,19 +467,16 @@ PEM_DecodeFinal(PEM_ENCODE_CTX *ctx, unsigned char *out, int *outl) } static int -get_line(unsigned char *in, char *buf) +get_line(unsigned char *in, int inlen, char *buf, int buflen) { - int i = 0; - int len = 0; - while ((in[i] != '\n')) { + while ((i < inlen) && (i < buflen) && (in[i] != '\n')) { buf[i] = in[i]; i++; - len++; } - return (len); + return (i); } KMF_RETURN @@ -499,13 +496,13 @@ Pem2Der(unsigned char *in, int inlen, (void) memset(buf, 0, sizeof (buf)); - for (;;) { + while (total < inlen) { /* * get a line (ended at '\n'), which returns * number of bytes in the line */ - i = get_line(in + total, buf); - if (i <= 0) { + i = get_line(in + total, inlen - total, buf, sizeof (buf)); + if (i == 0) { kmf_rv = KMF_ERR_ENCODING; goto err; } @@ -542,11 +539,11 @@ Pem2Der(unsigned char *in, int inlen, dataB[0] = '\0'; - for (;;) { + while (total < inlen) { (void) memset(buf, 0, 1024); - i = get_line(in+total, buf); + i = get_line(in+total, inlen - total, buf, sizeof (buf)); - if (i <= 0) break; + if (i == 0) break; j = i; while ((j >= 0) && (buf[j] <= ' ')) @@ -571,6 +568,9 @@ Pem2Der(unsigned char *in, int inlen, bl += j; } + if (nameB == NULL) + goto err; + i = strlen(nameB); if ((strncmp(buf, "-----END ", 9) != 0) || (strncmp(nameB, &(buf[9]), i) != 0) || diff --git a/usr/src/lib/libkmf/libkmf/common/policy.c b/usr/src/lib/libkmf/libkmf/common/policy.c index d9c3b1b754..dc9cd8213d 100644 --- a/usr/src/lib/libkmf/libkmf/common/policy.c +++ b/usr/src/lib/libkmf/libkmf/common/policy.c @@ -18,7 +18,7 @@ * * CDDL HEADER END * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -307,7 +307,7 @@ kmf_ekuname_to_oid(char *ekuname) } char * -kmf_oid_to_eku_string(KMF_OID *oid) +kmf_oid_to_ekuname(KMF_OID *oid) { int i; for (i = 0; i < num_ekus; i++) { diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers index 08ad0b561f..ce6d8d9aa2 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers @@ -18,7 +18,7 @@ # # CDDL HEADER END # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -48,7 +48,6 @@ SUNWprivate_1.1 { OpenSSL_GetSymKeyValue; OpenSSL_ImportCRL; OpenSSL_IsCRLFile; - OpenSSL_IsCertFile; OpenSSL_ListCRL; OpenSSL_SignData; OpenSSL_StoreCert; diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c index 78f9af1665..fb5af181d1 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* @@ -4716,57 +4716,6 @@ out: return (ret); } -/* - * Check a file to see if it is a certficate file with PEM or DER format. - * If success, return its format in the pformat argument. - */ -KMF_RETURN -OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, - KMF_ENCODE_FORMAT *pformat) -{ - KMF_RETURN ret = KMF_OK; - KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; - BIO *bio = NULL; - X509 *xcert = NULL; - - if (filename == NULL) { - return (KMF_ERR_BAD_PARAMETER); - } - - ret = kmf_get_file_format(filename, pformat); - if (ret != KMF_OK) - return (ret); - - bio = BIO_new_file(filename, "rb"); - if (bio == NULL) { - SET_ERROR(kmfh, ERR_get_error()); - ret = KMF_ERR_OPEN_FILE; - goto out; - } - - if ((*pformat) == KMF_FORMAT_PEM) { - if ((xcert = PEM_read_bio_X509(bio, NULL, - NULL, NULL)) == NULL) { - ret = KMF_ERR_BAD_CERTFILE; - } - } else if ((*pformat) == KMF_FORMAT_ASN1) { - if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { - ret = KMF_ERR_BAD_CERTFILE; - } - } else { - ret = KMF_ERR_BAD_CERTFILE; - } - -out: - if (bio != NULL) - (void) BIO_free(bio); - - if (xcert != NULL) - X509_free(xcert); - - return (ret); -} - KMF_RETURN OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, KMF_RAW_SYM_KEY *rkey) diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c index 6cf3de2517..ad4043c065 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c @@ -2630,7 +2630,7 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, boolean_t is_token = B_TRUE, is_private = B_FALSE; KMF_KEY_HANDLE *keys; uint32_t *numkeys; - KMF_CREDENTIAL cred; + KMF_CREDENTIAL *cred = NULL; KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE; char *findLabel, *idstr; KMF_KEY_ALG keytype = KMF_KEYALG_NONE; @@ -2733,15 +2733,11 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, * Authenticate if the object is a token object, * a private or secred key, or if the user passed in credentials. */ - if ((rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, - (void *)&cred, NULL)) == KMF_OK) { - if (cred.credlen > 0) { - rv = pk11_authenticate(handle, &cred); - if (rv != KMF_OK) - return (rv); - } - } else { - rv = KMF_OK; /* cred is optional */ + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred != NULL && (cred->credlen > 0)) { + rv = pk11_authenticate(handle, cred); + if (rv != KMF_OK) + return (rv); } keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); @@ -3156,7 +3152,7 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, uint32_t attrkeylen = 0; uint32_t keylen_size = sizeof (uint32_t); char *keylabel = NULL; - KMF_CREDENTIAL cred; + KMF_CREDENTIAL *cred = NULL; uint32_t is_sensitive = B_FALSE; uint32_t is_not_extractable = B_FALSE; @@ -3324,12 +3320,11 @@ KMFPK11_CreateSymKey(KMF_HANDLE_T handle, SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); i++; - rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, - (void *)&cred, NULL); - if (rv != KMF_OK) + cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (cred == NULL) return (KMF_ERR_BAD_PARAMETER); - rv = pk11_authenticate(handle, &cred); + rv = pk11_authenticate(handle, cred); if (rv != KMF_OK) { return (rv); } @@ -3414,21 +3409,19 @@ KMFPK11_SetTokenPin(KMF_HANDLE_T handle, CK_RV rv = CKR_OK; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CK_SESSION_HANDLE session = NULL; - KMF_CREDENTIAL oldcred = {NULL, 0}; - KMF_CREDENTIAL newcred = {NULL, 0}; + KMF_CREDENTIAL *oldcred; + KMF_CREDENTIAL *newcred; CK_SLOT_ID slotid; if (handle == NULL || attrlist == NULL || numattr == 0) return (KMF_ERR_BAD_PARAMETER); - rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, - (void *)&oldcred, NULL); - if (rv != KMF_OK) + oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); + if (oldcred == NULL) return (KMF_ERR_BAD_PARAMETER); - rv = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr, - (void *)&newcred, NULL); - if (rv != KMF_OK) + newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr); + if (newcred == NULL) return (KMF_ERR_BAD_PARAMETER); rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr, @@ -3439,10 +3432,10 @@ KMFPK11_SetTokenPin(KMF_HANDLE_T handle, * If a slot wasn't given, the user must pass * a token label so we can find the slot here. */ - rv = kmf_get_string_attr(KMF_TOKEN_LABEL_ATTR, attrlist, - numattr, &tokenlabel); - if (rv != KMF_OK) - return (rv); + tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, + numattr); + if (tokenlabel == NULL) + return (KMF_ERR_BAD_PARAMETER); rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid); if (rv != KMF_OK) @@ -3458,8 +3451,8 @@ KMFPK11_SetTokenPin(KMF_HANDLE_T handle, } rv = C_SetPIN(session, - (CK_BYTE *)oldcred.cred, oldcred.credlen, - (CK_BYTE *)newcred.cred, newcred.credlen); + (CK_BYTE *)oldcred->cred, oldcred->credlen, + (CK_BYTE *)newcred->cred, newcred->credlen); if (rv != CKR_OK) { SET_ERROR(kmfh, rv); |
