On Mon, Mar 29, 2021 at 01:22:20PM +0200, Claudio Jeker wrote: > On Mon, Mar 29, 2021 at 01:19:21PM +0200, Claudio Jeker wrote: > > On Mon, Mar 29, 2021 at 12:42:02PM +0200, Theo Buehler wrote: > > > On Mon, Mar 29, 2021 at 10:38:54AM +0200, Claudio Jeker wrote: > > > > Replace a super strange way to translate some binary blob into a hex > > > > string. > > > > The code drops the : from the string but this is fine, the : is just > > > > visual fluff. I used the same function in the not yet finished RRDP > > > > codebase and there I don't want the extra ':'. > > > > > > Yes, that's much better. > > > > > > Another detail that changes is that the hexadecimal digits will now be > > > lower case. Trading one byte overallocation for a free overflow check > > > is reasonable. The explicit NUL termination out[i * 2] = '\0' is not > > > really needed since we calloc, but it's probably fine to be explicit. > > > > Yeah, I decided to overallocate by one but have calloc() do the overflow > > check. Also I flipped to uppercase hex since both Job and you mentioned > > it. I just prefer the explicit NUL termination, if someone copy pastes the > > code somewhere else where no calloc() happens then such an implicit > > side-effect could introduce a bug. > > > > > ok tb > > > > > > for the diff as it is (also for moving the function to x509.c) > > > > I also renamed the function to hex_encode() so it fits with > > base64_decode() which sits in tal.c. I consider to move those functions > > plus a soon needed hex_decode() into a new file (encoding.c). > >
Sounds good. > And here is the diff I wanted to attach but forgot. ok > > -- > :wq Claudio > > Index: extern.h > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v > retrieving revision 1.58 > diff -u -p -r1.58 extern.h > --- extern.h 29 Mar 2021 06:50:44 -0000 1.58 > +++ extern.h 29 Mar 2021 11:09:57 -0000 > @@ -433,6 +433,7 @@ int io_recvfd(int, void *, size_t); > > /* X509 helpers. */ > > +char *hex_encode(const unsigned char *, size_t); > char *x509_get_aia(X509 *, const char *); > char *x509_get_aki(X509 *, int, const char *); > char *x509_get_ski(X509 *, const char *); > Index: x509.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v > retrieving revision 1.19 > diff -u -p -r1.19 x509.c > --- x509.c 29 Mar 2021 06:50:44 -0000 1.19 > +++ x509.c 29 Mar 2021 11:09:40 -0000 > @@ -30,9 +30,32 @@ > #include "extern.h" > > /* > + * Convert binary buffer of size dsz into an upper-case hex-string. > + * Returns pointer to the newly allocated string. Function can't fail. > + */ > +char * > +hex_encode(const unsigned char *in, size_t insz) > +{ > + const char hex[] = "0123456789ABCDEF"; > + size_t i; > + char *out; > + > + if ((out = calloc(2, insz + 1)) == NULL) > + err(1, NULL); > + > + for (i = 0; i < insz; i++) { > + out[i * 2] = hex[in[i] >> 4]; > + out[i * 2 + 1] = hex[in[i] & 0xf]; > + } > + out[i * 2] = '\0'; > + > + return out; > +} > + > +/* > * Parse X509v3 authority key identifier (AKI), RFC 6487 sec. 4.8.3. > * Returns the AKI or NULL if it could not be parsed. > - * The AKI is formatted as aa:bb:cc:dd, with each being a hex value. > + * The AKI is formatted as a hex string. > */ > char * > x509_get_aki(X509 *x, int ta, const char *fn) > @@ -40,8 +63,7 @@ x509_get_aki(X509 *x, int ta, const char > const unsigned char *d; > AUTHORITY_KEYID *akid; > ASN1_OCTET_STRING *os; > - int i, dsz, crit; > - char buf[4]; > + int dsz, crit; > char *res = NULL; > > akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &crit, NULL); > @@ -80,16 +102,7 @@ x509_get_aki(X509 *x, int ta, const char > goto out; > } > > - /* Make room for [hex1, hex2, ":"]*, NUL. */ > - > - if ((res = calloc(dsz * 3 + 1, 1)) == NULL) > - err(1, NULL); > - > - for (i = 0; i < dsz; i++) { > - snprintf(buf, sizeof(buf), "%02X:", d[i]); > - strlcat(res, buf, dsz * 3 + 1); > - } > - res[dsz * 3 - 1] = '\0'; > + res = hex_encode(d, dsz); > out: > AUTHORITY_KEYID_free(akid); > return res; > @@ -98,15 +111,14 @@ out: > /* > * Parse X509v3 subject key identifier (SKI), RFC 6487 sec. 4.8.2. > * Returns the SKI or NULL if it could not be parsed. > - * The SKI is formatted as aa:bb:cc:dd, with each being a hex value. > + * The SKI is formatted as a hex string. > */ > char * > x509_get_ski(X509 *x, const char *fn) > { > const unsigned char *d; > ASN1_OCTET_STRING *os; > - int i, dsz, crit; > - char buf[4]; > + int dsz, crit; > char *res = NULL; > > os = X509_get_ext_d2i(x, NID_subject_key_identifier, &crit, NULL); > @@ -130,16 +142,7 @@ x509_get_ski(X509 *x, const char *fn) > goto out; > } > > - /* Make room for [hex1, hex2, ":"]*, NUL. */ > - > - if ((res = calloc(dsz * 3 + 1, 1)) == NULL) > - err(1, NULL); > - > - for (i = 0; i < dsz; i++) { > - snprintf(buf, sizeof(buf), "%02X:", d[i]); > - strlcat(res, buf, dsz * 3 + 1); > - } > - res[dsz * 3 - 1] = '\0'; > + res = hex_encode(d, dsz); > out: > ASN1_OCTET_STRING_free(os); > return res; > @@ -270,14 +273,19 @@ out: > return crl; > } > > +/* > + * Parse X509v3 authority key identifier (AKI) from the CRL. > + * This is matched against the string from x509_get_ski() above. > + * Returns the AKI or NULL if it could not be parsed. > + * The AKI is formatted as a hex string. > + */ > char * > x509_crl_get_aki(X509_CRL *crl, const char *fn) > { > const unsigned char *d; > AUTHORITY_KEYID *akid; > ASN1_OCTET_STRING *os; > - int i, dsz, crit; > - char buf[4]; > + int dsz, crit; > char *res = NULL; > > akid = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, &crit, > @@ -315,16 +323,7 @@ x509_crl_get_aki(X509_CRL *crl, const ch > goto out; > } > > - /* Make room for [hex1, hex2, ":"]*, NUL. */ > - > - if ((res = calloc(dsz * 3 + 1, 1)) == NULL) > - err(1, NULL); > - > - for (i = 0; i < dsz; i++) { > - snprintf(buf, sizeof(buf), "%02X:", d[i]); > - strlcat(res, buf, dsz * 3 + 1); > - } > - res[dsz * 3 - 1] = '\0'; > + res = hex_encode(d, dsz); > out: > AUTHORITY_KEYID_free(akid); > return res;