summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorWyllys Ingersoll <wyllys.ingersoll@sun.com>2009-10-20 09:39:20 -0700
committerWyllys Ingersoll <wyllys.ingersoll@sun.com>2009-10-20 09:39:20 -0700
commit56664548661c43ae04de4a32bce3510ed36aeaf9 (patch)
treef23bd96c130e11e5b94c31a26273a2001020b565 /usr/src
parent069f55e237020c4a4907b235fc38fafc6442ce94 (diff)
downloadillumos-gate-56664548661c43ae04de4a32bce3510ed36aeaf9.tar.gz
6889197 libkmf uses realloc incorrectly
6889730 pktool fails to add EKUs to CSR and Cert requests 6889224 pktool incorrectly generates SAN
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/cmd-crypto/pktool/common.c5
-rw-r--r--usr/src/lib/libkmf/ber_der/common/encode.c8
-rw-r--r--usr/src/lib/libkmf/ber_der/common/io.c27
-rw-r--r--usr/src/lib/libkmf/ber_der/common/mapfile-vers2
-rw-r--r--usr/src/lib/libkmf/ber_der/inc/ber_der.h6
-rw-r--r--usr/src/lib/libkmf/libkmf/common/generalop.c132
6 files changed, 148 insertions, 32 deletions
diff --git a/usr/src/cmd/cmd-crypto/pktool/common.c b/usr/src/cmd/cmd-crypto/pktool/common.c
index a6c649a120..8c95c2e480 100644
--- a/usr/src/cmd/cmd-crypto/pktool/common.c
+++ b/usr/src/cmd/cmd-crypto/pktool/common.c
@@ -1128,6 +1128,7 @@ free_eku_list(EKU_LIST *ekus)
}
free(ekus->ekulist);
free(ekus->critlist);
+ free(ekus);
}
}
@@ -1166,6 +1167,10 @@ verify_ekunames(char *ekuliststr, EKU_LIST **ekulist)
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.
*/
diff --git a/usr/src/lib/libkmf/ber_der/common/encode.c b/usr/src/lib/libkmf/ber_der/common/encode.c
index 50e89d7c2f..73fe1b0ddf 100644
--- a/usr/src/lib/libkmf/ber_der/common/encode.c
+++ b/usr/src/lib/libkmf/ber_der/common/encode.c
@@ -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_start_seqorset(BerElement *ber, ber_tag_t tag)
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);
}
diff --git a/usr/src/lib/libkmf/ber_der/common/io.c b/usr/src/lib/libkmf/ber_der/common/io.c
index e946252e2b..e0a16141da 100644
--- a/usr/src/lib/libkmf/ber_der/common/io.c
+++ b/usr/src/lib/libkmf/ber_der/common/io.c
@@ -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 @@ kmfber_read(BerElement *ber, char *buf, ber_len_t len)
* 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 @@ kmfber_realloc(BerElement *ber, ber_len_t len)
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 @@ kmfber_realloc(BerElement *ber, ber_len_t len)
/* 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 @@ kmfber_realloc(BerElement *ber, ber_len_t len)
* 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 @@ kmfber_realloc(BerElement *ber, ber_len_t len)
s->sos_ptr = ber->ber_buf + off;
}
}
+ if (freeold && oldbuf != NULL)
+ free(oldbuf);
return (0);
}
@@ -162,11 +164,10 @@ void
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 @@ kmfder_init(const struct berval *bv)
/* 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 @@ kmfber_init(const struct berval *bv)
/* 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);
}
diff --git a/usr/src/lib/libkmf/ber_der/common/mapfile-vers b/usr/src/lib/libkmf/ber_der/common/mapfile-vers
index 591db3eb67..0a97cd2eab 100644
--- a/usr/src/lib/libkmf/ber_der/common/mapfile-vers
+++ b/usr/src/lib/libkmf/ber_der/common/mapfile-vers
@@ -63,6 +63,7 @@ SUNWprivate_1.1 {
ExtractX509CertParts;
GetKeyFromSpki;
kmfber_alloc;
+ kmfber_bvfree;
kmfber_first_element;
kmfber_flatten;
kmfber_free;
@@ -70,6 +71,7 @@ SUNWprivate_1.1 {
kmfber_next_element;
kmfber_printf;
kmfber_read;
+ kmfber_realloc;
kmfber_scanf;
kmfber_write;
kmfder_alloc;
diff --git a/usr/src/lib/libkmf/ber_der/inc/ber_der.h b/usr/src/lib/libkmf/ber_der/inc/ber_der.h
index 72a98e665c..abf112351d 100644
--- a/usr/src/lib/libkmf/ber_der/inc/ber_der.h
+++ b/usr/src/lib/libkmf/ber_der/inc/ber_der.h
@@ -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 @@ struct berval *kmfber_bvdup(const struct berval *);
*/
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
diff --git a/usr/src/lib/libkmf/libkmf/common/generalop.c b/usr/src/lib/libkmf/libkmf/common/generalop.c
index bbfdf152b0..f2a179b026 100644
--- a/usr/src/lib/libkmf/libkmf/common/generalop.c
+++ b/usr/src/lib/libkmf/libkmf/common/generalop.c
@@ -1699,6 +1699,7 @@ encode_krb5(char *name, KMF_DATA *derdata)
{
KMF_RETURN rv = KMF_OK;
char *at, *realm;
+ char *slash, *inst = NULL;
BerElement *asn1 = NULL;
BerValue *extdata = NULL;
@@ -1706,42 +1707,149 @@ encode_krb5(char *name, KMF_DATA *derdata)
if (at == NULL)
return (KMF_ERR_ENCODING);
- realm = at+1;
+ realm = at + 1;
*at = 0;
- if ((asn1 = kmfder_alloc()) == NULL)
- return (KMF_ERR_MEMORY);
+ /*
+ * 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, "{Tli", 0xa0, 3, 0x01) == -1)
+ 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, "{D{", &KMFOID_PKINIT_san) == -1)
+ 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;
- if (kmfber_printf(asn1, "l", strlen(realm)) == -1)
+ /* 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, "l", strlen(name)) == -1)
+ if (kmfber_printf(asn1, "Tl", 0xA1, extdata->bv_len) == -1)
goto cleanup;
- if (kmfber_write(asn1, name, strlen(name), 0) != strlen(name))
+ if (kmfber_write(asn1, extdata->bv_val,
+ extdata->bv_len, 0) != extdata->bv_len)
goto cleanup;
- if (kmfber_printf(asn1, "}}") == -1)
+ 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 @@ encode_altname(char *namedata,
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: