ITS#5070 use lutil_str2bin() for certificate serialNumbers

Still need to fix serialNumberAndIssuerPretty to accept hex
This commit is contained in:
Howard Chu 2007-10-01 06:55:02 +00:00
parent 4d58197880
commit 4ad821910c

View file

@ -3062,9 +3062,11 @@ serialNumberAndIssuerNormalize(
struct berval *out,
void *ctx )
{
struct berval sn, sn2, i, ni;
char sbuf[64], *stmp = sbuf;
int rc;
ber_len_t n;
struct berval sn, i, ni;
int is_hex = 0;
assert( in != NULL );
assert( out != NULL );
@ -3177,8 +3179,26 @@ serialNumberAndIssuerNormalize(
sn.bv_len++;
}
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_DIGIT( sn.bv_val[sn.bv_len] )) break;
if ( sn.bv_val[0] == '0' && ( sn.bv_val[1] == 'x' ||
sn.bv_val[1] == 'X' )) {
is_hex = 1;
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_HEX( sn.bv_val[sn.bv_len] )) break;
}
} else if ( sn.bv_val[0] == '\'' ) {
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_HEX( sn.bv_val[sn.bv_len] )) break;
}
if ( sn.bv_val[sn.bv_len] == '\'' &&
sn.bv_val[sn.bv_len+1] == 'H' )
is_hex = 1;
else
return LDAP_INVALID_SYNTAX;
sn.bv_len += 2;
} else {
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_DIGIT( sn.bv_val[sn.bv_len] )) break;
}
}
if (!( sn.bv_len > neg )) return LDAP_INVALID_SYNTAX;
@ -3265,8 +3285,26 @@ serialNumberAndIssuerNormalize(
sn.bv_len++;
}
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_DIGIT( sn.bv_val[sn.bv_len] )) break;
if ( sn.bv_val[0] == '0' && ( sn.bv_val[1] == 'x' ||
sn.bv_val[1] == 'X' )) {
is_hex = 1;
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_HEX( sn.bv_val[sn.bv_len] )) break;
}
} else if ( sn.bv_val[0] == '\'' ) {
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_HEX( sn.bv_val[sn.bv_len] )) break;
}
if ( sn.bv_val[sn.bv_len] == '\'' &&
sn.bv_val[sn.bv_len+1] == 'H' )
is_hex = 1;
else
return LDAP_INVALID_SYNTAX;
sn.bv_len += 2;
} else {
for( ; sn.bv_len < x.bv_len; sn.bv_len++ ) {
if ( !ASCII_DIGIT( sn.bv_val[sn.bv_len] )) break;
}
}
if (!( sn.bv_len > neg )) return LDAP_INVALID_SYNTAX;
@ -3301,15 +3339,27 @@ serialNumberAndIssuerNormalize(
if( rc ) return LDAP_INVALID_SYNTAX;
/* make room from sn + "$" */
/* Convert sn to canonical hex */
if ( sn.bv_len > sizeof( sbuf )) {
stmp = slap_sl_malloc( sn.bv_len, ctx );
}
sn2.bv_val = stmp;
sn2.bv_len = sn.bv_len;
if ( lutil_str2bin( &sn, &sn2 )) {
rc = LDAP_INVALID_SYNTAX;
goto leave;
}
/* make room for sn + "$" */
out->bv_len = STRLENOF( "{ serialNumber , issuer \"\" }" )
+ sn.bv_len + ni.bv_len;
+ ( sn2.bv_len * 2 + 3 ) + ni.bv_len;
out->bv_val = slap_sl_malloc( out->bv_len + 1, ctx );
if( out->bv_val == NULL ) {
out->bv_len = 0;
slap_sl_free( ni.bv_val, ctx );
return LDAP_OTHER;
rc = LDAP_OTHER;
goto leave;
}
n = 0;
@ -3318,7 +3368,17 @@ serialNumberAndIssuerNormalize(
n = STRLENOF( "{ serialNumber " );
AC_MEMCPY( &out->bv_val[n], sn.bv_val, sn.bv_len );
n += sn.bv_len;
{
int j;
unsigned char *v = sn2.bv_val;
out->bv_val[n++] = '\'';
for ( j = 0; j < sn2.bv_len; j++ ) {
sprintf( &out->bv_val[n], "%02x", v[j] );
n += 2;
}
out->bv_val[n++] = '\'';
out->bv_val[n++] = 'H';
}
AC_MEMCPY( &out->bv_val[n], ", issuer \"", STRLENOF( ", issuer \"" ));
n += STRLENOF( ", issuer \"" );
@ -3336,9 +3396,12 @@ serialNumberAndIssuerNormalize(
Debug( LDAP_DEBUG_TRACE, "<<< serialNumberAndIssuerNormalize: <%s>\n",
out->bv_val, 0, 0 );
leave:
if ( stmp != sbuf )
slap_sl_free( stmp, ctx );
slap_sl_free( ni.bv_val, ctx );
return LDAP_SUCCESS;
return rc;
}
static int
@ -3378,20 +3441,16 @@ certificateExactNormalize(
tag = ber_get_int( ber, &i ); /* version */
}
/* NOTE: move the test here from certificateNormalize,
/* NOTE: move the test here from certificateValidate,
* so that we can validate certs with serial longer
* than sizeof(ber_int_t) */
tag = ber_peek_tag( ber, &len ); /* serial */
/* Use hex format. [-]0x123456789abcdef
* Don't try to make special cases for multi-precision math
* support here, normalized values need to be canonical and
* consistent from machine to machine.
/* Use hex format. '123456789abcdef'H
*/
if ( len > sizeof(ber_int_t) ) {
{
unsigned char *ptr;
char *sptr;
char sign = 0;
tag = ber_skip_tag( ber, &len );
ptr = (unsigned char *)ber->ber_ptr;
@ -3401,7 +3460,6 @@ certificateExactNormalize(
if ( ptr[0] & 0x80 ) {
if (( ptr[0] == 0xff ) && ( ptr[1] & 0x80 ))
return LDAP_INVALID_SYNTAX;
sign = -1;
} else if ( ptr[0] == 0 ) {
if (!( ptr[1] & 0x80 ))
return LDAP_INVALID_SYNTAX;
@ -3409,25 +3467,18 @@ certificateExactNormalize(
len--;
}
seriallen = len * 2 + 3; /* leading 0x, NUL */
if ( sign )
seriallen++;
seriallen = len * 2 + 4; /* quotes, H, NUL */
if ( seriallen > sizeof( serialbuf ))
serial = slap_sl_malloc( seriallen, ctx );
sptr = serial;
if ( sign )
*sptr++ = '-';
*sptr++ = '0';
*sptr++ = 'x';
*sptr++ = '\'';
for ( i = 0; i<len; i++ ) {
sprintf( sptr, "%02x", sign ? 256 - ptr[i] : ptr[i] );
sptr += 2;
}
*sptr++ = '\'';
*sptr++ = 'H';
seriallen--;
} else {
tag = ber_get_int( ber, &i ); /* serial */
seriallen = snprintf( serialbuf, sizeof(serialbuf), "%d", i );
}
tag = ber_skip_tag( ber, &len ); /* SignatureAlg */
ber_skip_data( ber, len );