ref: 9e08127ba6a4754fae8afcc6bca9d8b299180632
parent: 8fd1aa262681ee7380df46dd8fc0db066969320a
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Apr 15 19:51:52 EDT 2016
libsec: x509: convert to UTF8 from BMPString and UNIString, reject \0 bytes
--- a/sys/src/libsec/port/x509.c
+++ b/sys/src/libsec/port/x509.c
@@ -478,6 +478,7 @@
pval->u.setval = vl;
}
break;
+
case UTF8String:
case NumericString:
case PrintableString:
@@ -491,13 +492,64 @@
case GeneralString:
case UniversalString:
case BMPString:
- /* TODO: figure out when character set conversion is necessary */
err = octet_decode(&p, pend, length, isconstr, &va);
if(err == ASN_OK) {
- pval->tag = VString;
- pval->u.stringval = (char*)emalloc(va->len+1);
- memmove(pval->u.stringval, va->data, va->len);
- pval->u.stringval[va->len] = 0;
+ uchar *s;
+ char *d;
+ Rune r;
+ int n;
+
+ switch(kind){
+ case UniversalString:
+ n = va->len / 4;
+ d = emalloc(n*UTFmax+1);
+ pval->u.stringval = d;
+ s = va->data;
+ while(n > 0){
+ r = s[0]<<24 | s[1]<<16 | s[2]<<8 | s[3];
+ if(r == 0)
+ break;
+ n--;
+ s += 4;
+ d += runetochar(d, &r);
+ }
+ *d = 0;
+ break;
+ case BMPString:
+ n = va->len / 2;
+ d = emalloc(n*UTFmax+1);
+ pval->u.stringval = d;
+ s = va->data;
+ while(n > 0){
+ r = s[0]<<8 | s[1];
+ if(r == 0)
+ break;
+ n--;
+ s += 2;
+ d += runetochar(d, &r);
+ }
+ *d = 0;
+ break;
+ default:
+ n = va->len;
+ d = emalloc(n+1);
+ pval->u.stringval = d;
+ s = va->data;
+ while(n > 0){
+ if((*d = *s) == 0)
+ break;
+ n--;
+ s++;
+ d++;
+ }
+ *d = 0;
+ break;
+ }
+ if(n != 0){
+ err = ASN_EINVAL;
+ free(pval->u.stringval);
+ } else
+ pval->tag = VString;
free(va);
}
break;