int type, unsigned short flags, char *quotes, char_io *io_ch,
void *arg)
{
- int i, outlen, len;
+ int i, outlen, len, charwidth;
unsigned short orflags;
unsigned char *p, *q;
unsigned long c;
p = buf;
q = buf + buflen;
outlen = 0;
+ charwidth = type & BUF_TYPE_WIDTH_MASK;
+
+ switch (charwidth) {
+ case 4:
+ if (buflen & 3) {
+ ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+ return -1;
+ }
+ break;
+ case 2:
+ if (buflen & 1) {
+ ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH);
+ return -1;
+ }
+ break;
+ default:
+ break;
+ }
+
while (p != q) {
if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
orflags = CHARTYPE_FIRST_ESC_2253;
else
orflags = 0;
- switch (type & BUF_TYPE_WIDTH_MASK) {
+
+ switch (charwidth) {
case 4:
c = ((unsigned long)*p++) << 24;
c |= ((unsigned long)*p++) << 16;
i = UTF8_getc(p, buflen, &c);
if (i < 0)
return -1; /* Invalid UTF8String */
+ buflen -= i;
p += i;
break;
default:
*out = stmp.data;
return stmp.length;
}
-
-/* Return 1 if host is a valid hostname and 0 otherwise */
-int asn1_valid_host(const ASN1_STRING *host)
-{
- int hostlen = host->length;
- const unsigned char *hostptr = host->data;
- int type = host->type;
- int i;
- signed char width = -1;
- unsigned short chflags = 0, prevchflags;
-
- if (type > 0 && type < 31)
- width = tag2nbyte[type];
- if (width == -1 || hostlen == 0)
- return 0;
- /* Treat UTF8String as width 1 as any MSB set is invalid */
- if (width == 0)
- width = 1;
- for (i = 0 ; i < hostlen; i+= width) {
- prevchflags = chflags;
- /* Value must be <= 0x7F: check upper bytes are all zeroes */
- if (width == 4) {
- if (*hostptr++ != 0 || *hostptr++ != 0 || *hostptr++ != 0)
- return 0;
- } else if (width == 2) {
- if (*hostptr++ != 0)
- return 0;
- }
- if (*hostptr > 0x7f)
- return 0;
- chflags = char_type[*hostptr++];
- if (!(chflags & (CHARTYPE_HOST_ANY | CHARTYPE_HOST_WILD))) {
- /* Nothing else allowed at start or end of string */
- if (i == 0 || i == hostlen - 1)
- return 0;
- /* Otherwise invalid if not dot or hyphen */
- if (!(chflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN)))
- return 0;
- /*
- * If previous is dot or hyphen then illegal unless both
- * are hyphens: as .- -. .. are all illegal
- */
- if (prevchflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN)
- && ((prevchflags & CHARTYPE_HOST_DOT)
- || (chflags & CHARTYPE_HOST_DOT)))
- return 0;
- }
- }
- return 1;
-}