From 8018924efd3b4abbce6bad2b367546faa559f6c2 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 30 Dec 2010 19:38:57 +0000 Subject: [PATCH] ITS#6741 support Bitstring in ldap_X509dn2bv() --- libraries/libldap/tls2.c | 94 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c index eea1b37f2e..e0c0408d29 100644 --- a/libraries/libldap/tls2.c +++ b/libraries/libldap/tls2.c @@ -967,6 +967,93 @@ find_oid( struct berval *oid ) return NULL; } +/* Converts BER Bitstring value to LDAP BitString value (RFC4517) + * + * berValue : IN + * rfc4517Value: OUT + * + * berValue and ldapValue should not be NULL + */ + +#define BITS_PER_BYTE 8 +#define SQUOTE_LENGTH 1 +#define B_CHAR_LENGTH 1 +#define STR_OVERHEAD (2*SQUOTE_LENGTH + B_CHAR_LENGTH) + +static int +der_to_ldap_BitString (struct berval *berValue, + struct berval *ldapValue) +{ + ber_len_t bitPadding=0; + ber_len_t bits, maxBits; + char *tmpStr; + unsigned char byte; + ber_len_t bitLength; + ber_len_t valLen; + unsigned char* valPtr; + + ldapValue->bv_len=0; + ldapValue->bv_val=NULL; + + /* Gets padding and points to binary data */ + valLen=berValue->bv_len; + valPtr=(unsigned char*)berValue->bv_val; + if (valLen) { + bitPadding=(ber_len_t)(valPtr[0]); + valLen--; + valPtr++; + } + /* If Block is non DER encoding fixes to DER encoding */ + if (bitPadding >= BITS_PER_BYTE) { + if (valLen*BITS_PER_BYTE > bitPadding ) { + valLen-=(bitPadding/BITS_PER_BYTE); + bitPadding%=BITS_PER_BYTE; + } else { + valLen=0; + bitPadding=0; + } + } + /* Just in case bad encoding */ + if (valLen*BITS_PER_BYTE < bitPadding ) { + bitPadding=0; + valLen=0; + } + + /* Gets buffer to hold RFC4517 Bit String format */ + bitLength=valLen*BITS_PER_BYTE-bitPadding; + tmpStr=LDAP_MALLOC(bitLength + STR_OVERHEAD + 1); + + if (!tmpStr) + return LDAP_NO_MEMORY; + + ldapValue->bv_val=tmpStr; + ldapValue->bv_len=bitLength + STR_OVERHEAD; + + /* Formatting in '*binary-digit'B format */ + maxBits=BITS_PER_BYTE; + *tmpStr++ ='\''; + while(valLen) { + byte=*valPtr; + if (valLen==1) + maxBits-=bitPadding; + for (bits=0; bitsla_value ); + newAVA->la_flags |= LDAP_AVA_NONPRINTABLE; +allocd: newAVA->la_flags |= LDAP_AVA_FREE_VALUE; if (rc != LDAP_SUCCESS) goto nomem; - newAVA->la_flags |= LDAP_AVA_NONPRINTABLE; break; case LBER_TAG_UTF8: newAVA->la_flags |= LDAP_AVA_NONPRINTABLE; @@ -1135,6 +1223,10 @@ to_utf8: rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value ); /* These are always 7-bit strings */ newAVA->la_value = Val; break; + case LBER_BITSTRING: + /* X.690 bitString value converted to RFC4517 Bit String */ + rc = der_to_ldap_BitString( &Val, &newAVA->la_value ); + goto allocd; default: /* Not a string type at all */ newAVA->la_flags = 0; -- 2.39.5