diff options
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); | 
