diff options
| author | Greg Hudson <ghudson@mit.edu> | 2012-01-09 21:03:58 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2012-01-09 21:03:58 +0000 |
| commit | 2be4076efedd845c04db91d7cbbf57cd86353465 (patch) | |
| tree | e6c2eb2287b6f7ad48aeae7821890084c4a13393 /src/lib | |
| parent | bde5e9efadbdf0fb0b2d1dd16efcb83e82e433e4 (diff) | |
| download | krb5-2be4076efedd845c04db91d7cbbf57cd86353465.tar.gz krb5-2be4076efedd845c04db91d7cbbf57cd86353465.tar.xz krb5-2be4076efedd845c04db91d7cbbf57cd86353465.zip | |
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.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25626 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/krb5/asn.1/asn1_decode.c | 26 | ||||
| -rw-r--r-- | src/lib/krb5/asn.1/asn1_decode.h | 3 | ||||
| -rw-r--r-- | src/lib/krb5/asn.1/asn1_k_decode.c | 11 |
3 files changed, 35 insertions, 5 deletions
diff --git a/src/lib/krb5/asn.1/asn1_decode.c b/src/lib/krb5/asn.1/asn1_decode.c index 53e2045495..1ded579b81 100644 --- a/src/lib/krb5/asn.1/asn1_decode.c +++ b/src/lib/krb5/asn.1/asn1_decode.c @@ -197,6 +197,32 @@ asn1_decode_generalstring(asn1buf *buf, unsigned int *retlen, char **val) 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) diff --git a/src/lib/krb5/asn.1/asn1_decode.h b/src/lib/krb5/asn.1/asn1_decode.h index 0e14491de6..7573b4fb71 100644 --- a/src/lib/krb5/asn.1/asn1_decode.h +++ b/src/lib/krb5/asn.1/asn1_decode.h @@ -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_error_code asn1_decode_octetstring(asn1buf *buf, unsigned int *retlen, 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); /* diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c index b2471004aa..e0c827c4f1 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.c +++ b/src/lib/krb5/asn.1/asn1_k_decode.c @@ -1515,11 +1515,12 @@ asn1_decode_kdc_dh_key_info(asn1buf *buf, krb5_kdc_dh_key_info *val) 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(); |
