svn rev #25626: trunk/src/ lib/krb5/asn.1/ plugins/preauth/pkinit/

ghudson@MIT.EDU ghudson at MIT.EDU
Mon Jan 9 16:03:58 EST 2012


http://src.mit.edu/fisheye/changelog/krb5/?cs=25626
Commit By: ghudson
Log Message:
Make dh_key_info encoder and decoder symmetric

The dh_key_info encoder expects subjectPublicKey to contain the
contents of a bit string, but the decoder outputs the DER encoding of
the bit string including tag.  The PKINIT client code expects this, so
everything works, but the encoder and decoder should be symmetric.
Change the decoder to process the bit string (adding a bit string
decoding primitive) and modify the PKINIT client code to expect only
the bit string contents.


Changed Files:
U   trunk/src/lib/krb5/asn.1/asn1_decode.c
U   trunk/src/lib/krb5/asn.1/asn1_decode.h
U   trunk/src/lib/krb5/asn.1/asn1_k_decode.c
U   trunk/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
U   trunk/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
Modified: trunk/src/lib/krb5/asn.1/asn1_decode.c
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_decode.c	2012-01-09 20:13:10 UTC (rev 25625)
+++ trunk/src/lib/krb5/asn.1/asn1_decode.c	2012-01-09 21:03:58 UTC (rev 25626)
@@ -197,7 +197,33 @@
     cleanup();
 }
 
+asn1_error_code
+asn1_decode_bitstring(asn1buf *buf, unsigned int *retlen, char **val)
+{
+    setup();
+    asn1_octet unused;
 
+    tag(ASN1_BITSTRING);
+
+    /* Get the number of unused bits in the last byte (0-7). */
+    retval = asn1buf_remove_octet(buf, &unused);
+    if (retval)
+        return retval;
+    if (unused > 7)
+        return ASN1_BAD_FORMAT;
+
+    retval = asn1buf_remove_charstring(buf, length - 1, val);
+    if (retval)
+        return retval;
+
+    /* Mask out unused bits (unnecessary for correct DER, but be safe). */
+    if (length > 1)
+        (*val)[length - 2] &= (0xff << unused);
+
+    *retlen = length - 1;
+    return 0;
+}
+
 asn1_error_code
 asn1_decode_null(asn1buf *buf)
 {

Modified: trunk/src/lib/krb5/asn.1/asn1_decode.h
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_decode.h	2012-01-09 20:13:10 UTC (rev 25625)
+++ trunk/src/lib/krb5/asn.1/asn1_decode.h	2012-01-09 21:03:58 UTC (rev 25626)
@@ -45,6 +45,7 @@
  *  asn1_decode_octetstring
  *  asn1_decode_charstring
  *  asn1_decode_generalstring
+ *  asn1_decode_bitstring
  *  asn1_decode_null
  *  asn1_decode_printablestring
  *  asn1_decode_ia5string
@@ -72,6 +73,8 @@
                                         asn1_octet **val);
 asn1_error_code asn1_decode_generalstring(asn1buf *buf, unsigned int *retlen,
                                           char **val);
+asn1_error_code asn1_decode_bitstring(asn1buf *buf, unsigned int *retlen,
+                                      char **val);
 asn1_error_code asn1_decode_charstring(asn1buf *buf, unsigned int *retlen,
                                        char **val);
 /*

Modified: trunk/src/lib/krb5/asn.1/asn1_k_decode.c
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_k_decode.c	2012-01-09 20:13:10 UTC (rev 25625)
+++ trunk/src/lib/krb5/asn.1/asn1_k_decode.c	2012-01-09 21:03:58 UTC (rev 25626)
@@ -1515,11 +1515,12 @@
     setup();
     val->subjectPublicKey.data = NULL;
     { begin_structure();
-        retval = asn1buf_remove_charstring(&subbuf, taglen,
-                                           &val->subjectPublicKey.data);
-        if (retval) clean_return(retval);
-        val->subjectPublicKey.length = taglen;
-        next_tag();
+        /* Special handling for [0] IMPLICIT BIT STRING */
+        error_if_bad_tag(0);
+        if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
+            clean_return(ASN1_BAD_ID);
+        get_lenfield_body(val->subjectPublicKey.length,
+                          val->subjectPublicKey.data, asn1_decode_bitstring);
         get_field(val->nonce, 1, asn1_decode_int32);
         opt_field(val->dhKeyExpiration, 2, asn1_decode_kerberos_time, 0);
         end_structure();

Modified: trunk/src/plugins/preauth/pkinit/pkinit_crypto_nss.c
===================================================================
--- trunk/src/plugins/preauth/pkinit/pkinit_crypto_nss.c	2012-01-09 20:13:10 UTC (rev 25625)
+++ trunk/src/plugins/preauth/pkinit/pkinit_crypto_nss.c	2012-01-09 21:03:58 UTC (rev 25626)
@@ -950,26 +950,21 @@
     return i;
 }
 
-/* Decode a bitstring that contains an unsigned integer, and return just the
- * bits that make up that integer. */
+/* Decode a DER unsigned integer, and return just the bits that make up that
+ * integer. */
 static int
 secitem_from_dh_pubval(PLArenaPool *pool,
                        unsigned char *dh_pubkey, unsigned int dh_pubkey_len,
                        SECItem *bits_out)
 {
-    SECItem tmp, uinteger;
+    SECItem tmp;
 
     tmp.data = dh_pubkey;
     tmp.len = dh_pubkey_len;
-    memset(&uinteger, 0, sizeof(uinteger));
-    if (SEC_ASN1DecodeItem(pool, &uinteger,
-                           SEC_ASN1_GET(SEC_BitStringTemplate),
-                           &tmp) != SECSuccess)
-        return ENOMEM;
     memset(bits_out, 0, sizeof(*bits_out));
     if (SEC_ASN1DecodeItem(pool, bits_out,
                            SEC_ASN1_GET(SEC_IntegerTemplate),
-                           &uinteger) != SECSuccess)
+                           &tmp) != SECSuccess)
         return ENOMEM;
     return 0;
 }

Modified: trunk/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
===================================================================
--- trunk/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c	2012-01-09 20:13:10 UTC (rev 25625)
+++ trunk/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c	2012-01-09 21:03:58 UTC (rev 25626)
@@ -147,9 +147,6 @@
  unsigned char *data, unsigned int data_len,
  unsigned char **decoded_data, unsigned int *decoded_data_len);
 
-static krb5_error_code der_decode_data
-(unsigned char *, long, unsigned char **, long *);
-
 static krb5_error_code
 create_krb5_invalidCertificates(krb5_context context,
                                 pkinit_plg_crypto_context plg_cryptoctx,
@@ -2647,25 +2644,15 @@
     BIGNUM *server_pub_key = NULL;
     ASN1_INTEGER *pub_key = NULL;
     const unsigned char *p = NULL;
-    unsigned char *data = NULL;
-    long data_len;
 
-    /* decode subjectPublicKey (retrieve INTEGER from OCTET_STRING) */
-
-    if (der_decode_data(subjectPublicKey_data, (long)subjectPublicKey_length,
-                        &data, &data_len) != 0) {
-        pkiDebug("failed to decode subjectPublicKey\n");
-        retval = -1;
-        goto cleanup;
-    }
-
     *client_key_len = DH_size(cryptoctx->dh);
     if ((*client_key = malloc(*client_key_len)) == NULL) {
         retval = ENOMEM;
         goto cleanup;
     }
-    p = data;
-    if ((pub_key = d2i_ASN1_INTEGER(NULL, &p, data_len)) == NULL)
+    p = subjectPublicKey_data;
+    pub_key = d2i_ASN1_INTEGER(NULL, &p, (long)subjectPublicKey_length);
+    if (pub_key == NULL)
         goto cleanup;
     if ((server_pub_key = ASN1_INTEGER_to_BN(pub_key, NULL)) == NULL)
         goto cleanup;
@@ -2682,8 +2669,6 @@
         BN_free(server_pub_key);
     if (pub_key != NULL)
         ASN1_INTEGER_free(pub_key);
-    if (data != NULL)
-        free (data);
 
     return retval;
 
@@ -2692,8 +2677,6 @@
     *client_key = NULL;
     if (pub_key != NULL)
         ASN1_INTEGER_free(pub_key);
-    if (data != NULL)
-        free (data);
 
     return retval;
 }
@@ -5999,33 +5982,6 @@
     return(out);
 }
 
-static krb5_error_code
-der_decode_data(unsigned char *data, long data_len,
-                unsigned char **out, long *out_len)
-{
-    krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
-    ASN1_OCTET_STRING *s = NULL;
-    const unsigned char *p = data;
-
-    if ((s = d2i_ASN1_BIT_STRING(NULL, &p, data_len)) == NULL)
-        goto cleanup;
-    *out_len = s->length;
-    if ((*out = malloc((size_t) *out_len + 1)) == NULL) {
-        retval = ENOMEM;
-        goto cleanup;
-    }
-    memcpy(*out, s->data, (size_t) s->length);
-    (*out)[s->length] = '\0';
-
-    retval = 0;
-cleanup:
-    if (s != NULL)
-        ASN1_OCTET_STRING_free(s);
-
-    return retval;
-}
-
-
 #ifdef DEBUG_DH
 static void
 print_dh(DH * dh, char *msg)



More information about the cvs-krb5 mailing list