ref: 591ff71b0d952884bc917c3c491e448b9e7ebe08
parent: 85aede8a03a1e639557a2553eb0d98521307e8bb
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;
--
⑨