summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorwyllys <none@none>2008-02-20 16:42:06 -0800
committerwyllys <none@none>2008-02-20 16:42:06 -0800
commitd00756ccb34596a328f8a15d1965da5412d366d0 (patch)
tree7e086e15d7f37b4820231342edb72fb6b7e60a09 /usr/src/lib
parentf243d98a5f37cb011837c5ac9230d51aa966c997 (diff)
downloadillumos-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.c255
-rw-r--r--usr/src/lib/libkmf/include/kmfapi.h10
-rw-r--r--usr/src/lib/libkmf/include/kmfapiP.h115
-rw-r--r--usr/src/lib/libkmf/include/kmfpolicy.h5
-rw-r--r--usr/src/lib/libkmf/include/kmftypes.h55
-rw-r--r--usr/src/lib/libkmf/libkmf/common/certgetsetop.c10
-rw-r--r--usr/src/lib/libkmf/libkmf/common/certop.c173
-rw-r--r--usr/src/lib/libkmf/libkmf/common/csrcrlop.c189
-rw-r--r--usr/src/lib/libkmf/libkmf/common/generalop.c139
-rw-r--r--usr/src/lib/libkmf/libkmf/common/kmfoids.c23
-rw-r--r--usr/src/lib/libkmf/libkmf/common/mapfile-vers17
-rw-r--r--usr/src/lib/libkmf/libkmf/common/pem_encode.c26
-rw-r--r--usr/src/lib/libkmf/libkmf/common/policy.c4
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers3
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c53
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c51
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);