Mercurial > illumos > illumos-gate
changeset 10818:89e8703947be
6889197 libkmf uses realloc incorrectly
6889730 pktool fails to add EKUs to CSR and Cert requests
6889224 pktool incorrectly generates SAN
author | Wyllys Ingersoll <wyllys.ingersoll@sun.com> |
---|---|
date | Tue, 20 Oct 2009 09:39:20 -0700 |
parents | 7dfde45252f0 |
children | d41e0e73a69e |
files | usr/src/cmd/cmd-crypto/pktool/common.c usr/src/lib/libkmf/ber_der/common/encode.c usr/src/lib/libkmf/ber_der/common/io.c usr/src/lib/libkmf/ber_der/common/mapfile-vers usr/src/lib/libkmf/ber_der/inc/ber_der.h usr/src/lib/libkmf/libkmf/common/generalop.c |
diffstat | 6 files changed, 154 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/cmd-crypto/pktool/common.c Tue Oct 20 09:30:12 2009 -0700 +++ b/usr/src/cmd/cmd-crypto/pktool/common.c Tue Oct 20 09:39:20 2009 -0700 @@ -1128,6 +1128,7 @@ } free(ekus->ekulist); free(ekus->critlist); + free(ekus); } } @@ -1166,6 +1167,10 @@ if (ekuliststr == NULL || strlen(ekuliststr) == 0) return (0); + ekus = calloc(sizeof (EKU_LIST), 1); + if (ekus == NULL) + return (KMF_ERR_MEMORY); + /* * The list should be comma separated list of EKU Names. */
--- a/usr/src/lib/libkmf/ber_der/common/encode.c Tue Oct 20 09:30:12 2009 -0700 +++ b/usr/src/lib/libkmf/ber_der/common/encode.c Tue Oct 20 09:39:20 2009 -0700 @@ -30,12 +30,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <netinet/in.h> #include <inttypes.h> @@ -455,7 +453,9 @@ ber->ber_sos = new_sos; if (ber->ber_sos->sos_ptr > ber->ber_end) { - (void) realloc(ber, ber->ber_sos->sos_ptr - ber->ber_end); + if (kmfber_realloc(ber, ber->ber_sos->sos_ptr - + ber->ber_end) != 0) + return (-1); } return (0); }
--- a/usr/src/lib/libkmf/ber_der/common/io.c Tue Oct 20 09:30:12 2009 -0700 +++ b/usr/src/lib/libkmf/ber_der/common/io.c Tue Oct 20 09:39:20 2009 -0700 @@ -29,13 +29,10 @@ * is provided ``as is'' without express or implied warranty. */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - - #include <stdlib.h> #include <ber_der.h> #include "kmfber_int.h" @@ -69,7 +66,7 @@ * enlarge the ber buffer. * return 0 on success, -1 on error. */ -static int +int kmfber_realloc(BerElement *ber, ber_len_t len) { ber_uint_t need, have, total; @@ -77,6 +74,7 @@ Seqorset *s; size_t off; char *oldbuf; + boolean_t freeold = B_FALSE; have_bytes = ber->ber_end - ber->ber_buf; have = have_bytes / EXBUFSIZ; @@ -96,16 +94,19 @@ /* transition to malloc'd buffer */ if ((ber->ber_buf = (char *)malloc( (size_t)total)) == NULL) { + free(oldbuf); return (-1); } ber->ber_flags &= ~KMFBER_FLAG_NO_FREE_BUFFER; /* copy existing data into new malloc'd buffer */ (void) memmove(ber->ber_buf, oldbuf, have_bytes); + freeold = B_TRUE; } else { if ((ber->ber_buf = (char *)realloc( ber->ber_buf, (size_t)total)) == NULL) { return (-1); } + freeold = B_FALSE; /* it was just realloced */ } } @@ -116,7 +117,6 @@ * reset all the sos and ber pointers. Offsets would've been * a better idea... oh well. */ - if (ber->ber_buf != oldbuf) { ber->ber_ptr = ber->ber_buf + (ber->ber_ptr - oldbuf); @@ -128,6 +128,8 @@ s->sos_ptr = ber->ber_buf + off; } } + if (freeold && oldbuf != NULL) + free(oldbuf); return (0); } @@ -162,11 +164,10 @@ kmfber_free(BerElement *ber, int freebuf) { if (ber != NULL) { - if (freebuf && - !(ber->ber_flags & KMFBER_FLAG_NO_FREE_BUFFER)) { - free(ber->ber_buf); - } - free((char *)ber); + if (freebuf && + !(ber->ber_flags & KMFBER_FLAG_NO_FREE_BUFFER)) + free(ber->ber_buf); + free((char *)ber); } } @@ -351,7 +352,7 @@ /* copy data from the bv argument into BerElement */ /* XXXmcs: had to cast unsigned long bv_len to long */ if ((kmfber_write(ber, bv->bv_val, bv->bv_len, 0)) != - (ber_slen_t)bv->bv_len) { + (ber_slen_t)bv->bv_len) { kmfber_free(ber, 1); return (NULL); } @@ -379,7 +380,7 @@ /* copy data from the bv argument into BerElement */ /* XXXmcs: had to cast unsigned long bv_len to long */ if ((kmfber_write(ber, bv->bv_val, bv->bv_len, 0)) != - (ber_slen_t)bv->bv_len) { + (ber_slen_t)bv->bv_len) { kmfber_free(ber, 1); return (NULL); }
--- a/usr/src/lib/libkmf/ber_der/common/mapfile-vers Tue Oct 20 09:30:12 2009 -0700 +++ b/usr/src/lib/libkmf/ber_der/common/mapfile-vers Tue Oct 20 09:39:20 2009 -0700 @@ -63,6 +63,7 @@ ExtractX509CertParts; GetKeyFromSpki; kmfber_alloc; + kmfber_bvfree; kmfber_first_element; kmfber_flatten; kmfber_free; @@ -70,6 +71,7 @@ kmfber_next_element; kmfber_printf; kmfber_read; + kmfber_realloc; kmfber_scanf; kmfber_write; kmfder_alloc;
--- a/usr/src/lib/libkmf/ber_der/inc/ber_der.h Tue Oct 20 09:30:12 2009 -0700 +++ b/usr/src/lib/libkmf/ber_der/inc/ber_der.h Tue Oct 20 09:39:20 2009 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -22,8 +22,6 @@ * Reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This is the header file for some Basic Encoding Rules and Distinguished * Encoding Rules (BER/DER) routines. @@ -49,6 +47,7 @@ #define BER_IA5STRING 22 #define BER_UTCTIME 23 #define BER_GENTIME 24 +#define BER_GENERALSTRING 27 #define BER_UNIVERSAL_STRING 28 #define BER_BMP_STRING 30 @@ -114,6 +113,7 @@ */ extern int kmfber_printf(BerElement *, const char *, ...); extern int kmfber_flatten(BerElement *, struct berval **); +extern int kmfber_realloc(BerElement *, ber_len_t); /* * miscellaneous public routines
--- a/usr/src/lib/libkmf/libkmf/common/generalop.c Tue Oct 20 09:30:12 2009 -0700 +++ b/usr/src/lib/libkmf/libkmf/common/generalop.c Tue Oct 20 09:39:20 2009 -0700 @@ -1699,6 +1699,7 @@ { KMF_RETURN rv = KMF_OK; char *at, *realm; + char *slash, *inst = NULL; BerElement *asn1 = NULL; BerValue *extdata = NULL; @@ -1706,42 +1707,149 @@ if (at == NULL) return (KMF_ERR_ENCODING); - realm = at+1; + realm = at + 1; *at = 0; - if ((asn1 = kmfder_alloc()) == NULL) - return (KMF_ERR_MEMORY); - - if (kmfber_printf(asn1, "{D{", &KMFOID_PKINIT_san) == -1) + /* + * KRB5PrincipalName ::= SEQUENCE { + * realm [0] Realm, + * principalName [1] PrincipalName + * } + * + * KerberosString ::= GeneralString (IA5String) + * Realm ::= KerberosString + * PrincipalName ::= SEQUENCE { + * name-type [0] Int32, + * name-string [1] SEQUENCE OF KerberosString + * } + */ + + /* + * Construct the "principalName" first. + * + * The name may be split with a "/" to indicate a new instance. + * This must be separated in the ASN.1 + */ + slash = strchr(name, '/'); + if (slash != NULL) { + inst = name; + name = slash + 1; + *slash = 0; + } + if ((asn1 = kmfder_alloc()) == NULL) { + rv = KMF_ERR_MEMORY; goto cleanup; - - if (kmfber_printf(asn1, "l", strlen(realm)) == -1) - goto cleanup; - if (kmfber_write(asn1, realm, strlen(realm), 0) != strlen(realm)) + } + if (kmfber_printf(asn1, "{Tli", 0xa0, 3, 0x01) == -1) 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 (inst != NULL) { + if (kmfber_printf(asn1, "Tl{Tl", 0xA1, + strlen(inst) + strlen(name) + 6, + BER_GENERALSTRING, strlen(inst)) == -1) + goto cleanup; + if (kmfber_write(asn1, inst, strlen(inst), 0) != strlen(inst)) + goto cleanup; + if (kmfber_printf(asn1, "Tl", BER_GENERALSTRING, + strlen(name)) == -1) + goto cleanup; + if (kmfber_write(asn1, name, strlen(name), 0) != strlen(name)) + goto cleanup; + } else { + if (kmfber_printf(asn1, "Tl{Tl", 0xA1, + strlen(name) + 4, BER_GENERALSTRING, 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; } + kmfber_free(asn1, 1); + asn1 = NULL; + + /* Next construct the KRB5PrincipalNameSeq */ + if ((asn1 = kmfder_alloc()) == NULL) { + kmfber_bvfree(extdata); + rv = KMF_ERR_MEMORY; + goto cleanup; + } + if (kmfber_printf(asn1, "{TlTl", 0xA0, strlen(realm) + 2, + BER_GENERALSTRING, strlen(realm)) == -1) + goto cleanup; + if (kmfber_write(asn1, realm, strlen(realm), 0) != strlen(realm)) + goto cleanup; + if (kmfber_printf(asn1, "Tl", 0xA1, extdata->bv_len) == -1) + goto cleanup; + if (kmfber_write(asn1, extdata->bv_val, + extdata->bv_len, 0) != extdata->bv_len) + goto cleanup; + if (kmfber_printf(asn1, "}") == -1) + goto cleanup; + kmfber_bvfree(extdata); + extdata = NULL; + if (kmfber_flatten(asn1, &extdata) == -1) { + rv = KMF_ERR_ENCODING; + goto cleanup; + } + kmfber_free(asn1, 1); + asn1 = NULL; + + /* + * GeneralName ::= CHOICE { + * otherName [0] OtherName, + * ... + * } + * + * OtherName ::= SEQUENCE { + * type-id OBJECT IDENTIFIER, + * value [0] EXPLICIT ANY DEFINED BY type-id + * } + */ + + /* Now construct the SAN: OID + typed data. */ + if ((asn1 = kmfder_alloc()) == NULL) { + kmfber_bvfree(extdata); + rv = KMF_ERR_MEMORY; + goto cleanup; + } + if (kmfber_printf(asn1, "D", &KMFOID_PKINIT_san) == -1) + goto cleanup; + if (kmfber_printf(asn1, "Tl", 0xA0, extdata->bv_len) == -1) + goto cleanup; + if (kmfber_write(asn1, extdata->bv_val, + extdata->bv_len, 0) != extdata->bv_len) + goto cleanup; + kmfber_bvfree(extdata); + extdata = NULL; + if (kmfber_flatten(asn1, &extdata) == -1) { + rv = KMF_ERR_ENCODING; + goto cleanup; + } + kmfber_free(asn1, 1); + asn1 = NULL; derdata->Data = (uchar_t *)extdata->bv_val; + extdata->bv_val = NULL; /* clear it so it is not freed later */ derdata->Length = extdata->bv_len; - free(extdata); cleanup: if (asn1 != NULL) kmfber_free(asn1, 1); + if (extdata != NULL) + kmfber_bvfree(extdata); + if (*at == 0) *at = '@'; + if (inst != NULL) + *slash = '/'; + return (rv); } @@ -1864,14 +1972,14 @@ ret = DerEncodeName(&dnname, encodedname); } (void) kmf_free_dn(&dnname); - tagval = (0xA0 | nametype); + tagval = (0x80 | nametype); break; case GENNAME_KRB5PRINC: - tagval = (0x80 | GENNAME_OTHERNAME); + tagval = (0xA0 | GENNAME_OTHERNAME); ret = encode_krb5(namedata, encodedname); break; case GENNAME_SCLOGON_UPN: - tagval = (0x80 | GENNAME_OTHERNAME); + tagval = (0xA0 | GENNAME_OTHERNAME); ret = encode_sclogon(namedata, encodedname); break; default: