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 );
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;
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;
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;
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 \"" );
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
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;
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;
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 );