static int cpy_utf8(unsigned long value, void *arg);
static int is_printable(unsigned long value);
-/* This is the default mask for the mbstring functions: it is designed
- * to be a "safe" DirectoryString. Netscape messenger crashes when it
- * receives a certificate containing a BMPString so by default we don't
- * use them unless we have to.
- */
-
-static long dirstring_mask = B_ASN1_PRINTABLESTRING
- | B_ASN1_T61STRING | B_ASN1_BMPSTRING;
-
-void ASN1_STRING_set_default_mask(unsigned long mask)
-{
- dirstring_mask = mask;
-}
-
-unsigned long ASN1_STRING_get_default_mask(void)
-{
- return dirstring_mask;
-}
-
-/* This function sets the default to various "flavours" of configuration.
- * based on an ASCII string. Currently this is:
- * MASK:XXXX : a numerical mask value.
- * nobmp : Don't use BMPStrings (just Printable, T61).
- * pkix : PKIX recommendation in RFC2459.
- * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
- * default: the default value, Printable, T61, BMP.
- */
-
-int ASN1_STRING_set_default_mask_asc(char *p)
-{
- unsigned long mask;
- char *end;
- if(!strncmp(p, "MASK:", 5)) {
- if(!p[5]) return 0;
- mask = strtoul(p + 5, &end, 0);
- if(*end) return 0;
- } else if(!strcmp(p, "nobmp"))
- mask = B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING;
- else if(!strcmp(p, "pkix"))
- mask = B_ASN1_PRINTABLESTRING | B_ASN1_BMPSTRING;
- else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
- else if(!strcmp(p, "default"))
- mask = B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_BMPSTRING;
- else return 0;
- ASN1_STRING_set_default_mask(mask);
- return 1;
-}
-
/* These functions take a string in UTF8, ASCII or multibyte form and
* a mask of permissible ASN1 string types. It then works out the minimal
* type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
{
int str_type;
int ret;
+ char free_out;
int outform, outlen;
ASN1_STRING *dest;
unsigned char *p;
int nchar;
- unsigned char strbuf[32];
+ char strbuf[32];
int (*cpyfunc)(unsigned long,void *) = NULL;
if(len == -1) len = strlen((const char *)in);
- if(!mask) mask = dirstring_mask;
+ if(!mask) mask = DIRSTRING_TYPE;
/* First do a string check and work out the number of characters */
switch(inform) {
case MBSTRING_BMP:
if(len & 1) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
case MBSTRING_UNIV:
if(len & 3) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if(ret < 0) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
default:
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_UNKNOWN_FORMAT);
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
- if(minsize && (nchar < minsize)) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_SHORT);
- sprintf(strbuf, "%ld", minsize);
+ if((minsize > 0) && (nchar < minsize)) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
+ BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
ERR_add_error_data(2, "minsize=", strbuf);
return -1;
}
- if(maxsize && (nchar > maxsize)) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_LONG);
- sprintf(strbuf, "%ld", maxsize);
+ if((maxsize > 0) && (nchar > maxsize)) {
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
+ BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
ERR_add_error_data(2, "maxsize=", strbuf);
return -1;
}
/* Now work out minimal type (if any) */
if(traverse_string(in, len, inform, type_str, &mask) < 0) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_ILLEGAL_CHARACTERS);
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
}
if(!out) return str_type;
if(*out) {
+ free_out = 0;
dest = *out;
if(dest->data) {
dest->length = 0;
- Free(dest->data);
+ OPENSSL_free(dest->data);
dest->data = NULL;
}
dest->type = str_type;
} else {
+ free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if(!dest) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ERR_R_MALLOC_FAILURE);
return -1;
}
/* If both the same type just copy across */
if(inform == outform) {
if(!ASN1_STRING_set(dest, in, len)) {
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
return -1;
}
return str_type;
cpyfunc = cpy_utf8;
break;
}
- if(!(p = Malloc(outlen + 1))) {
- ASN1_STRING_free(dest);
- ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE);
+ if(!(p = OPENSSL_malloc(outlen + 1))) {
+ if(free_out) ASN1_STRING_free(dest);
+ ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
return -1;
}
dest->length = outlen;
value |= *p++;
len -= 2;
} else if(inform == MBSTRING_UNIV) {
- value = *p++ << 24;
- value |= *p++ << 16;
+ value = ((unsigned long)*p++) << 24;
+ value |= ((unsigned long)*p++) << 16;
value |= *p++ << 8;
value |= *p++;
len -= 4;
static int out_utf8(unsigned long value, void *arg)
{
- long *outlen;
+ int *outlen;
outlen = arg;
*outlen += UTF8_putc(NULL, -1, value);
return 1;
/* Note: we can't use 'isalnum' because certain accented
* characters may count as alphanumeric in some environments.
*/
+#ifndef CHARSET_EBCDIC
if((ch >= 'a') && (ch <= 'z')) return 1;
if((ch >= 'A') && (ch <= 'Z')) return 1;
if((ch >= '0') && (ch <= '9')) return 1;
if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
+#else /*CHARSET_EBCDIC*/
+ if((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) return 1;
+ if((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) return 1;
+ if((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) return 1;
+ if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) return 1;
+#endif /*CHARSET_EBCDIC*/
return 0;
}