66int pk_oid_str_to_num (const char * OID , unsigned long * oid , unsigned long * oidlen )
77{
88 unsigned long i , j , limit , oid_j ;
9- size_t OID_len ;
109
1110 LTC_ARGCHK (oidlen != NULL );
1211
1312 limit = * oidlen ;
1413 * oidlen = 0 ; /* make sure that we return zero oidlen on error */
15- for (i = 0 ; i < limit ; i ++ ) oid [i ] = 0 ;
16-
14+ if (oid != NULL ) {
15+ XMEMSET (oid , 0 , sizeof (* oid ) * limit );
16+ }
1717 if (OID == NULL ) return CRYPT_OK ;
18+ if (OID [0 ] == '\0' ) return CRYPT_OK ;
1819
19- OID_len = XSTRLEN (OID );
20- if (OID_len == 0 ) return CRYPT_OK ;
21-
22- for (i = 0 , j = 0 ; i < OID_len ; i ++ ) {
20+ for (i = 0 , j = 0 ; OID [i ] != '\0' ; i ++ ) {
2321 if (OID [i ] == '.' ) {
2422 if (++ j >= limit ) continue ;
2523 }
@@ -34,49 +32,74 @@ int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen
3432 }
3533 }
3634 if (j == 0 ) return CRYPT_ERROR ;
37- if ( j >= limit ) {
38- * oidlen = j ;
35+ * oidlen = j + 1 ;
36+ if ( j >= limit || oid == NULL ) {
3937 return CRYPT_BUFFER_OVERFLOW ;
4038 }
41- * oidlen = j + 1 ;
4239 return CRYPT_OK ;
4340}
4441
42+ typedef struct num_to_str {
43+ int err ;
44+ char * wr ;
45+ unsigned long max_len , res_len ;
46+ } num_to_str ;
47+
48+ static LTC_INLINE void s_wr (char c , num_to_str * w )
49+ {
50+ if (w -> res_len == ULONG_MAX ) {
51+ w -> err = CRYPT_OVERFLOW ;
52+ return ;
53+ }
54+ w -> res_len ++ ;
55+ if (w -> res_len > w -> max_len ) w -> wr = NULL ;
56+ if (w -> wr ) w -> wr [w -> max_len - w -> res_len ] = c ;
57+ }
58+
4559int pk_oid_num_to_str (const unsigned long * oid , unsigned long oidlen , char * OID , unsigned long * outlen )
4660{
4761 int i ;
48- unsigned long j , k ;
49- char tmp [ LTC_OID_MAX_STRLEN ] = { 0 } ;
62+ num_to_str w ;
63+ unsigned long j ;
5064
5165 LTC_ARGCHK (oid != NULL );
5266 LTC_ARGCHK (oidlen < INT_MAX );
5367 LTC_ARGCHK (outlen != NULL );
5468
55- for (i = oidlen - 1 , k = 0 ; i >= 0 ; i -- ) {
69+ if (OID == NULL || * outlen == 0 ) {
70+ w .max_len = ULONG_MAX ;
71+ w .wr = NULL ;
72+ } else {
73+ w .max_len = * outlen ;
74+ w .wr = OID ;
75+ }
76+ w .res_len = 0 ;
77+ w .err = CRYPT_OK ;
78+
79+ s_wr ('\0' , & w );
80+ for (i = oidlen ; i -- > 0 ;) {
5681 j = oid [i ];
5782 if (j == 0 ) {
58- tmp [k ] = '0' ;
59- if (++ k >= sizeof (tmp )) return CRYPT_ERROR ;
60- }
61- else {
83+ s_wr ('0' , & w );
84+ } else {
6285 while (j > 0 ) {
63- tmp [k ] = '0' + (j % 10 );
64- if (++ k >= sizeof (tmp )) return CRYPT_ERROR ;
86+ s_wr ('0' + (j % 10 ), & w );
6587 j /= 10 ;
6688 }
6789 }
6890 if (i > 0 ) {
69- tmp [k ] = '.' ;
70- if (++ k >= sizeof (tmp )) return CRYPT_ERROR ;
91+ s_wr ('.' , & w );
7192 }
7293 }
73- if (* outlen < k + 1 ) {
74- * outlen = k + 1 ;
94+ if (w .err != CRYPT_OK ) {
95+ return w .err ;
96+ }
97+ if (* outlen < w .res_len || OID == NULL ) {
98+ * outlen = w .res_len ;
7599 return CRYPT_BUFFER_OVERFLOW ;
76100 }
77101 LTC_ARGCHK (OID != NULL );
78- for (j = 0 ; j < k ; j ++ ) OID [j ] = tmp [k - j - 1 ];
79- OID [k ] = '\0' ;
80- * outlen = k ; /* the length without terminating NUL byte */
102+ XMEMMOVE (OID , OID + (w .max_len - w .res_len ), w .res_len );
103+ * outlen = w .res_len ;
81104 return CRYPT_OK ;
82105}
0 commit comments