mirror of
https://github.com/moparisthebest/curl
synced 2025-01-11 05:58:01 -05:00
x509asn1: cleanup and unify code layout
- rename 'n' to buflen in functions, and use size_t for them. Don't pass in negative buffer lengths. - move most function comments to above the function starts like we use to - remove several unnecessary typecasts (especially of NULL) Reviewed-by: Patrick Monnerat Closes #3582
This commit is contained in:
parent
5e1b5e6936
commit
d8b0318ad6
249
lib/x509asn1.c
249
lib/x509asn1.c
@ -120,7 +120,7 @@ static const char *getASN1Element(curl_asn1Element *elem,
|
|||||||
if an error occurs. */
|
if an error occurs. */
|
||||||
if(!beg || !end || beg >= end || !*beg ||
|
if(!beg || !end || beg >= end || !*beg ||
|
||||||
(size_t)(end - beg) > CURL_ASN1_MAX)
|
(size_t)(end - beg) > CURL_ASN1_MAX)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Process header byte. */
|
/* Process header byte. */
|
||||||
elem->header = beg;
|
elem->header = beg;
|
||||||
@ -129,12 +129,12 @@ static const char *getASN1Element(curl_asn1Element *elem,
|
|||||||
elem->class = (b >> 6) & 3;
|
elem->class = (b >> 6) & 3;
|
||||||
b &= 0x1F;
|
b &= 0x1F;
|
||||||
if(b == 0x1F)
|
if(b == 0x1F)
|
||||||
return (const char *) NULL; /* Long tag values not supported here. */
|
return NULL; /* Long tag values not supported here. */
|
||||||
elem->tag = b;
|
elem->tag = b;
|
||||||
|
|
||||||
/* Process length. */
|
/* Process length. */
|
||||||
if(beg >= end)
|
if(beg >= end)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
b = (unsigned char) *beg++;
|
b = (unsigned char) *beg++;
|
||||||
if(!(b & 0x80))
|
if(!(b & 0x80))
|
||||||
len = b;
|
len = b;
|
||||||
@ -142,69 +142,72 @@ static const char *getASN1Element(curl_asn1Element *elem,
|
|||||||
/* Unspecified length. Since we have all the data, we can determine the
|
/* Unspecified length. Since we have all the data, we can determine the
|
||||||
effective length by skipping element until an end element is found. */
|
effective length by skipping element until an end element is found. */
|
||||||
if(!elem->constructed)
|
if(!elem->constructed)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
elem->beg = beg;
|
elem->beg = beg;
|
||||||
while(beg < end && *beg) {
|
while(beg < end && *beg) {
|
||||||
beg = getASN1Element(&lelem, beg, end);
|
beg = getASN1Element(&lelem, beg, end);
|
||||||
if(!beg)
|
if(!beg)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(beg >= end)
|
if(beg >= end)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
elem->end = beg;
|
elem->end = beg;
|
||||||
return beg + 1;
|
return beg + 1;
|
||||||
}
|
}
|
||||||
else if((unsigned)b > (size_t)(end - beg))
|
else if((unsigned)b > (size_t)(end - beg))
|
||||||
return (const char *) NULL; /* Does not fit in source. */
|
return NULL; /* Does not fit in source. */
|
||||||
else {
|
else {
|
||||||
/* Get long length. */
|
/* Get long length. */
|
||||||
len = 0;
|
len = 0;
|
||||||
do {
|
do {
|
||||||
if(len & 0xFF000000L)
|
if(len & 0xFF000000L)
|
||||||
return (const char *) NULL; /* Lengths > 32 bits are not supported. */
|
return NULL; /* Lengths > 32 bits are not supported. */
|
||||||
len = (len << 8) | (unsigned char) *beg++;
|
len = (len << 8) | (unsigned char) *beg++;
|
||||||
} while(--b);
|
} while(--b);
|
||||||
}
|
}
|
||||||
if(len > (size_t)(end - beg))
|
if(len > (size_t)(end - beg))
|
||||||
return (const char *) NULL; /* Element data does not fit in source. */
|
return NULL; /* Element data does not fit in source. */
|
||||||
elem->beg = beg;
|
elem->beg = beg;
|
||||||
elem->end = beg + len;
|
elem->end = beg + len;
|
||||||
return elem->end;
|
return elem->end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search the null terminated OID or OID identifier in local table.
|
||||||
|
* Return the table entry pointer or NULL if not found.
|
||||||
|
*/
|
||||||
static const curl_OID * searchOID(const char *oid)
|
static const curl_OID * searchOID(const char *oid)
|
||||||
{
|
{
|
||||||
const curl_OID *op;
|
const curl_OID *op;
|
||||||
|
|
||||||
/* Search the null terminated OID or OID identifier in local table.
|
|
||||||
Return the table entry pointer or NULL if not found. */
|
|
||||||
|
|
||||||
for(op = OIDtable; op->numoid; op++)
|
for(op = OIDtable; op->numoid; op++)
|
||||||
if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
|
if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
|
||||||
return op;
|
return op;
|
||||||
|
|
||||||
return (const curl_OID *) NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 Boolean value into its string representation. Return the
|
||||||
|
* dynamically allocated string, or NULL if source is not an ASN.1 Boolean
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
|
||||||
static const char *bool2str(const char *beg, const char *end)
|
static const char *bool2str(const char *beg, const char *end)
|
||||||
{
|
{
|
||||||
/* Convert an ASN.1 Boolean value into its string representation.
|
|
||||||
Return the dynamically allocated string, or NULL if source is not an
|
|
||||||
ASN.1 Boolean value. */
|
|
||||||
|
|
||||||
if(end - beg != 1)
|
if(end - beg != 1)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
return strdup(*beg? "TRUE": "FALSE");
|
return strdup(*beg? "TRUE": "FALSE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 octet string to a printable string.
|
||||||
|
* Return the dynamically allocated string, or NULL if an error occurs.
|
||||||
|
*/
|
||||||
static const char *octet2str(const char *beg, const char *end)
|
static const char *octet2str(const char *beg, const char *end)
|
||||||
{
|
{
|
||||||
size_t n = end - beg;
|
size_t n = end - beg;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
/* Convert an ASN.1 octet string to a printable string.
|
|
||||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
|
||||||
|
|
||||||
if(n <= (SIZE_T_MAX - 1) / 3) {
|
if(n <= (SIZE_T_MAX - 1) / 3) {
|
||||||
buf = malloc(3 * n + 1);
|
buf = malloc(3 * n + 1);
|
||||||
if(buf)
|
if(buf)
|
||||||
@ -220,21 +223,22 @@ static const char *bit2str(const char *beg, const char *end)
|
|||||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
Return the dynamically allocated string, or NULL if an error occurs. */
|
||||||
|
|
||||||
if(++beg > end)
|
if(++beg > end)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
return octet2str(beg, end);
|
return octet2str(beg, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 integer value into its string representation.
|
||||||
|
* Return the dynamically allocated string, or NULL if source is not an
|
||||||
|
* ASN.1 integer value.
|
||||||
|
*/
|
||||||
static const char *int2str(const char *beg, const char *end)
|
static const char *int2str(const char *beg, const char *end)
|
||||||
{
|
{
|
||||||
unsigned long val = 0;
|
unsigned long val = 0;
|
||||||
size_t n = end - beg;
|
size_t n = end - beg;
|
||||||
|
|
||||||
/* Convert an ASN.1 integer value into its string representation.
|
|
||||||
Return the dynamically allocated string, or NULL if source is not an
|
|
||||||
ASN.1 integer value. */
|
|
||||||
|
|
||||||
if(!n)
|
if(!n)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
|
|
||||||
if(n > 4)
|
if(n > 4)
|
||||||
return octet2str(beg, end);
|
return octet2str(beg, end);
|
||||||
@ -249,6 +253,13 @@ static const char *int2str(const char *beg, const char *end)
|
|||||||
return curl_maprintf("%s%lx", val >= 10? "0x": "", val);
|
return curl_maprintf("%s%lx", val >= 10? "0x": "", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
|
||||||
|
* destination buffer dynamically. The allocation size will normally be too
|
||||||
|
* large: this is to avoid buffer overflows.
|
||||||
|
* Terminate the string with a nul byte and return the converted
|
||||||
|
* string length.
|
||||||
|
*/
|
||||||
static ssize_t
|
static ssize_t
|
||||||
utf8asn1str(char **to, int type, const char *from, const char *end)
|
utf8asn1str(char **to, int type, const char *from, const char *end)
|
||||||
{
|
{
|
||||||
@ -259,13 +270,7 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
|
|||||||
unsigned int wc;
|
unsigned int wc;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
/* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
|
*to = NULL;
|
||||||
destination buffer dynamically. The allocation size will normally be too
|
|
||||||
large: this is to avoid buffer overflows.
|
|
||||||
Terminate the string with a nul byte and return the converted
|
|
||||||
string length. */
|
|
||||||
|
|
||||||
*to = (char *) NULL;
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case CURL_ASN1_BMP_STRING:
|
case CURL_ASN1_BMP_STRING:
|
||||||
size = 2;
|
size = 2;
|
||||||
@ -341,97 +346,105 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
|
|||||||
return outlength;
|
return outlength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 String into its UTF-8 string representation.
|
||||||
|
* Return the dynamically allocated string, or NULL if an error occurs.
|
||||||
|
*/
|
||||||
static const char *string2str(int type, const char *beg, const char *end)
|
static const char *string2str(int type, const char *beg, const char *end)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
/* Convert an ASN.1 String into its UTF-8 string representation.
|
|
||||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
|
||||||
|
|
||||||
if(utf8asn1str(&buf, type, beg, end) < 0)
|
if(utf8asn1str(&buf, type, beg, end) < 0)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encodeUint(char *buf, int n, unsigned int x)
|
/*
|
||||||
|
* Decimal ASCII encode unsigned integer `x' into the buflen sized buffer at
|
||||||
|
* buf. Return the total number of encoded digits, even if larger than
|
||||||
|
* `buflen'.
|
||||||
|
*/
|
||||||
|
static size_t encodeUint(char *buf, size_t buflen, unsigned int x)
|
||||||
{
|
{
|
||||||
int i = 0;
|
size_t i = 0;
|
||||||
unsigned int y = x / 10;
|
unsigned int y = x / 10;
|
||||||
|
|
||||||
/* Decimal ASCII encode unsigned integer `x' in the `n'-byte buffer at `buf'.
|
|
||||||
Return the total number of encoded digits, even if larger than `n'. */
|
|
||||||
|
|
||||||
if(y) {
|
if(y) {
|
||||||
i = encodeUint(buf, n, y);
|
i = encodeUint(buf, buflen, y);
|
||||||
x -= y * 10;
|
x -= y * 10;
|
||||||
}
|
}
|
||||||
if(i < n)
|
if(i < buflen)
|
||||||
buf[i] = (char) ('0' + x);
|
buf[i] = (char) ('0' + x);
|
||||||
i++;
|
i++;
|
||||||
if(i < n)
|
if(i < buflen)
|
||||||
buf[i] = '\0'; /* Store a terminator if possible. */
|
buf[i] = '\0'; /* Store a terminator if possible. */
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encodeOID(char *buf, int n, const char *beg, const char *end)
|
/*
|
||||||
|
* Convert an ASN.1 OID into its dotted string representation.
|
||||||
|
* Store the result in th `n'-byte buffer at `buf'.
|
||||||
|
* Return the converted string length, or 0 on errors.
|
||||||
|
*/
|
||||||
|
static size_t encodeOID(char *buf, size_t buflen,
|
||||||
|
const char *beg, const char *end)
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
|
|
||||||
/* Convert an ASN.1 OID into its dotted string representation.
|
|
||||||
Store the result in th `n'-byte buffer at `buf'.
|
|
||||||
Return the converted string length, or -1 if an error occurs. */
|
|
||||||
|
|
||||||
/* Process the first two numbers. */
|
/* Process the first two numbers. */
|
||||||
y = *(const unsigned char *) beg++;
|
y = *(const unsigned char *) beg++;
|
||||||
x = y / 40;
|
x = y / 40;
|
||||||
y -= x * 40;
|
y -= x * 40;
|
||||||
i = encodeUint(buf, n, x);
|
i = encodeUint(buf, buflen, x);
|
||||||
if(i < n)
|
if(i < buflen)
|
||||||
buf[i] = '.';
|
buf[i] = '.';
|
||||||
i++;
|
i++;
|
||||||
i += encodeUint(buf + i, n - i, y);
|
if(i >= buflen)
|
||||||
|
i += encodeUint(NULL, 0, y);
|
||||||
|
else
|
||||||
|
i += encodeUint(buf + i, buflen - i, y);
|
||||||
|
|
||||||
/* Process the trailing numbers. */
|
/* Process the trailing numbers. */
|
||||||
while(beg < end) {
|
while(beg < end) {
|
||||||
if(i < n)
|
if(i < buflen)
|
||||||
buf[i] = '.';
|
buf[i] = '.';
|
||||||
i++;
|
i++;
|
||||||
x = 0;
|
x = 0;
|
||||||
do {
|
do {
|
||||||
if(x & 0xFF000000)
|
if(x & 0xFF000000)
|
||||||
return -1;
|
return 0;
|
||||||
y = *(const unsigned char *) beg++;
|
y = *(const unsigned char *) beg++;
|
||||||
x = (x << 7) | (y & 0x7F);
|
x = (x << 7) | (y & 0x7F);
|
||||||
} while(y & 0x80);
|
} while(y & 0x80);
|
||||||
i += encodeUint(buf + i, n - i, x);
|
if(i >= buflen)
|
||||||
|
i += encodeUint(NULL, 0, x);
|
||||||
|
else
|
||||||
|
i += encodeUint(buf + i, buflen - i, x);
|
||||||
}
|
}
|
||||||
if(i < n)
|
if(i < buflen)
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 OID into its dotted or symbolic string representation.
|
||||||
|
* Return the dynamically allocated string, or NULL if an error occurs.
|
||||||
|
*/
|
||||||
|
|
||||||
static const char *OID2str(const char *beg, const char *end, bool symbolic)
|
static const char *OID2str(const char *beg, const char *end, bool symbolic)
|
||||||
{
|
{
|
||||||
char *buf = (char *) NULL;
|
char *buf = NULL;
|
||||||
const curl_OID * op;
|
|
||||||
int n;
|
|
||||||
char dummy[1];
|
|
||||||
|
|
||||||
/* Convert an ASN.1 OID into its dotted or symbolic string representation.
|
|
||||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
|
||||||
|
|
||||||
if(beg < end) {
|
if(beg < end) {
|
||||||
n = encodeOID(dummy, 0, beg, end);
|
size_t buflen = encodeOID(NULL, 0, beg, end);
|
||||||
if(n >= 0) {
|
if(buflen) {
|
||||||
buf = malloc(n + 1);
|
buf = malloc(buflen + 1); /* one extra for the zero byte */
|
||||||
if(buf) {
|
if(buf) {
|
||||||
encodeOID(buf, n, beg, end);
|
encodeOID(buf, buflen, beg, end);
|
||||||
buf[n] = '\0';
|
buf[buflen] = '\0';
|
||||||
|
|
||||||
if(symbolic) {
|
if(symbolic) {
|
||||||
op = searchOID(buf);
|
const curl_OID *op = searchOID(buf);
|
||||||
if(op) {
|
if(op) {
|
||||||
free(buf);
|
free(buf);
|
||||||
buf = strdup(op->textoid);
|
buf = strdup(op->textoid);
|
||||||
@ -471,7 +484,7 @@ static const char *GTime2str(const char *beg, const char *end)
|
|||||||
sec2 = fracp[-1];
|
sec2 = fracp[-1];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scan for timezone, measure fractional seconds. */
|
/* Scan for timezone, measure fractional seconds. */
|
||||||
@ -507,15 +520,16 @@ static const char *GTime2str(const char *beg, const char *end)
|
|||||||
sep, tzl, tzp);
|
sep, tzl, tzp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 UTC time to a printable string.
|
||||||
|
* Return the dynamically allocated string, or NULL if an error occurs.
|
||||||
|
*/
|
||||||
static const char *UTime2str(const char *beg, const char *end)
|
static const char *UTime2str(const char *beg, const char *end)
|
||||||
{
|
{
|
||||||
const char *tzp;
|
const char *tzp;
|
||||||
size_t tzl;
|
size_t tzl;
|
||||||
const char *sec;
|
const char *sec;
|
||||||
|
|
||||||
/* Convert an ASN.1 UTC time to a printable string.
|
|
||||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
|
||||||
|
|
||||||
for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++)
|
for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++)
|
||||||
;
|
;
|
||||||
/* Get the seconds. */
|
/* Get the seconds. */
|
||||||
@ -526,12 +540,12 @@ static const char *UTime2str(const char *beg, const char *end)
|
|||||||
case 2:
|
case 2:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process timezone. */
|
/* Process timezone. */
|
||||||
if(tzp >= end)
|
if(tzp >= end)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
if(*tzp == 'Z') {
|
if(*tzp == 'Z') {
|
||||||
tzp = "GMT";
|
tzp = "GMT";
|
||||||
end = tzp + 3;
|
end = tzp + 3;
|
||||||
@ -546,13 +560,14 @@ static const char *UTime2str(const char *beg, const char *end)
|
|||||||
tzl, tzp);
|
tzl, tzp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 element to a printable string.
|
||||||
|
* Return the dynamically allocated string, or NULL if an error occurs.
|
||||||
|
*/
|
||||||
static const char *ASN1tostr(curl_asn1Element *elem, int type)
|
static const char *ASN1tostr(curl_asn1Element *elem, int type)
|
||||||
{
|
{
|
||||||
/* Convert an ASN.1 element to a printable string.
|
|
||||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
|
||||||
|
|
||||||
if(elem->constructed)
|
if(elem->constructed)
|
||||||
return (const char *) NULL; /* No conversion of structured elements. */
|
return NULL; /* No conversion of structured elements. */
|
||||||
|
|
||||||
if(!type)
|
if(!type)
|
||||||
type = elem->tag; /* Type not forced: use element tag as type. */
|
type = elem->tag; /* Type not forced: use element tag as type. */
|
||||||
@ -586,10 +601,14 @@ static const char *ASN1tostr(curl_asn1Element *elem, int type)
|
|||||||
return string2str(type, elem->beg, elem->end);
|
return string2str(type, elem->beg, elem->end);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (const char *) NULL; /* Unsupported. */
|
return NULL; /* Unsupported. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
/*
|
||||||
|
* ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at
|
||||||
|
* `buf'. Return the total string length, even if larger than `buflen'.
|
||||||
|
*/
|
||||||
|
static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn)
|
||||||
{
|
{
|
||||||
curl_asn1Element rdn;
|
curl_asn1Element rdn;
|
||||||
curl_asn1Element atv;
|
curl_asn1Element atv;
|
||||||
@ -601,9 +620,6 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||||||
const char *p3;
|
const char *p3;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
/* ASCII encode distinguished name at `dn' into the `n'-byte buffer at `buf'.
|
|
||||||
Return the total string length, even if larger than `n'. */
|
|
||||||
|
|
||||||
for(p1 = dn->beg; p1 < dn->end;) {
|
for(p1 = dn->beg; p1 < dn->end;) {
|
||||||
p1 = getASN1Element(&rdn, p1, dn->end);
|
p1 = getASN1Element(&rdn, p1, dn->end);
|
||||||
if(!p1)
|
if(!p1)
|
||||||
@ -627,7 +643,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||||||
for(p3 = str; isupper(*p3); p3++)
|
for(p3 = str; isupper(*p3); p3++)
|
||||||
;
|
;
|
||||||
for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
|
for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
|
||||||
if(l < n)
|
if(l < buflen)
|
||||||
buf[l] = *p3;
|
buf[l] = *p3;
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
@ -635,14 +651,14 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||||||
|
|
||||||
/* Encode attribute name. */
|
/* Encode attribute name. */
|
||||||
for(p3 = str; *p3; p3++) {
|
for(p3 = str; *p3; p3++) {
|
||||||
if(l < n)
|
if(l < buflen)
|
||||||
buf[l] = *p3;
|
buf[l] = *p3;
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
free((char *) str);
|
free((char *) str);
|
||||||
|
|
||||||
/* Generate equal sign. */
|
/* Generate equal sign. */
|
||||||
if(l < n)
|
if(l < buflen)
|
||||||
buf[l] = '=';
|
buf[l] = '=';
|
||||||
l++;
|
l++;
|
||||||
|
|
||||||
@ -651,7 +667,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||||||
if(!str)
|
if(!str)
|
||||||
return -1;
|
return -1;
|
||||||
for(p3 = str; *p3; p3++) {
|
for(p3 = str; *p3; p3++) {
|
||||||
if(l < n)
|
if(l < buflen)
|
||||||
buf[l] = *p3;
|
buf[l] = *p3;
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
@ -662,28 +678,30 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an ASN.1 distinguished name into a printable string.
|
||||||
|
* Return the dynamically allocated string, or NULL if an error occurs.
|
||||||
|
*/
|
||||||
static const char *DNtostr(curl_asn1Element *dn)
|
static const char *DNtostr(curl_asn1Element *dn)
|
||||||
{
|
{
|
||||||
char *buf = (char *) NULL;
|
char *buf = NULL;
|
||||||
ssize_t n = encodeDN(buf, 0, dn);
|
ssize_t buflen = encodeDN(NULL, 0, dn);
|
||||||
|
|
||||||
/* Convert an ASN.1 distinguished name into a printable string.
|
if(buflen >= 0) {
|
||||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
buf = malloc(buflen + 1);
|
||||||
|
|
||||||
if(n >= 0) {
|
|
||||||
buf = malloc(n + 1);
|
|
||||||
if(buf) {
|
if(buf) {
|
||||||
encodeDN(buf, n + 1, dn);
|
encodeDN(buf, buflen + 1, dn);
|
||||||
buf[n] = '\0';
|
buf[buflen] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (const char *) buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* X509 parser.
|
* ASN.1 parse an X509 certificate into structure subfields.
|
||||||
|
* Syntax is assumed to have already been checked by the SSL backend.
|
||||||
|
* See RFC 5280.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Curl_parseX509(curl_X509certificate *cert,
|
int Curl_parseX509(curl_X509certificate *cert,
|
||||||
const char *beg, const char *end)
|
const char *beg, const char *end)
|
||||||
{
|
{
|
||||||
@ -692,10 +710,6 @@ int Curl_parseX509(curl_X509certificate *cert,
|
|||||||
const char *ccp;
|
const char *ccp;
|
||||||
static const char defaultVersion = 0; /* v1. */
|
static const char defaultVersion = 0; /* v1. */
|
||||||
|
|
||||||
/* ASN.1 parse an X509 certificate into structure subfields.
|
|
||||||
Syntax is assumed to have already been checked by the SSL backend.
|
|
||||||
See RFC 5280. */
|
|
||||||
|
|
||||||
cert->certificate.header = NULL;
|
cert->certificate.header = NULL;
|
||||||
cert->certificate.beg = beg;
|
cert->certificate.beg = beg;
|
||||||
cert->certificate.end = end;
|
cert->certificate.end = end;
|
||||||
@ -802,13 +816,14 @@ int Curl_parseX509(curl_X509certificate *cert,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy at most 64-characters, terminate with a newline and returns the
|
||||||
|
* effective number of stored characters.
|
||||||
|
*/
|
||||||
static size_t copySubstring(char *to, const char *from)
|
static size_t copySubstring(char *to, const char *from)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* Copy at most 64-characters, terminate with a newline and returns the
|
|
||||||
effective number of stored characters. */
|
|
||||||
|
|
||||||
for(i = 0; i < 64; i++) {
|
for(i = 0; i < 64; i++) {
|
||||||
to[i] = *from;
|
to[i] = *from;
|
||||||
if(!*from++)
|
if(!*from++)
|
||||||
@ -1105,15 +1120,15 @@ static const char *checkOID(const char *beg, const char *end,
|
|||||||
|
|
||||||
ccp = getASN1Element(&e, beg, end);
|
ccp = getASN1Element(&e, beg, end);
|
||||||
if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
|
if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
|
|
||||||
p = OID2str(e.beg, e.end, FALSE);
|
p = OID2str(e.beg, e.end, FALSE);
|
||||||
if(!p)
|
if(!p)
|
||||||
return (const char *) NULL;
|
return NULL;
|
||||||
|
|
||||||
matched = !strcmp(p, oid);
|
matched = !strcmp(p, oid);
|
||||||
free((char *) p);
|
free((char *) p);
|
||||||
return matched? ccp: (const char *) NULL;
|
return matched? ccp: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_verifyhost(struct connectdata *conn,
|
CURLcode Curl_verifyhost(struct connectdata *conn,
|
||||||
|
Loading…
Reference in New Issue
Block a user