mirror of https://github.com/moparisthebest/curl
x509asn1: make several functions static
and remove the private SIZE_T_MAX define and use the generic one. Closes #2902
This commit is contained in:
parent
362e9cc89b
commit
d26717584c
122
lib/x509asn1.c
122
lib/x509asn1.c
|
@ -40,10 +40,6 @@
|
|||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* For overflow checks. */
|
||||
#define CURL_SIZE_T_MAX ((size_t)-1)
|
||||
|
||||
|
||||
/* ASN.1 OIDs. */
|
||||
static const char cnOID[] = "2.5.4.3"; /* Common name. */
|
||||
static const char sanOID[] = "2.5.29.17"; /* Subject alternative name. */
|
||||
|
@ -108,8 +104,8 @@ static const curl_OID OIDtable[] = {
|
|||
*/
|
||||
|
||||
|
||||
const char *Curl_getASN1Element(curl_asn1Element *elem,
|
||||
const char *beg, const char *end)
|
||||
static const char *getASN1Element(curl_asn1Element *elem,
|
||||
const char *beg, const char *end)
|
||||
{
|
||||
unsigned char b;
|
||||
unsigned long len;
|
||||
|
@ -146,7 +142,7 @@ const char *Curl_getASN1Element(curl_asn1Element *elem,
|
|||
return (const char *) NULL;
|
||||
elem->beg = beg;
|
||||
while(beg < end && *beg) {
|
||||
beg = Curl_getASN1Element(&lelem, beg, end);
|
||||
beg = getASN1Element(&lelem, beg, end);
|
||||
if(!beg)
|
||||
return (const char *) NULL;
|
||||
}
|
||||
|
@ -206,7 +202,7 @@ static const char *octet2str(const char *beg, const char *end)
|
|||
/* Convert an ASN.1 octet string to a printable string.
|
||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
||||
|
||||
if(n <= (CURL_SIZE_T_MAX - 1) / 3) {
|
||||
if(n <= (SIZE_T_MAX - 1) / 3) {
|
||||
buf = malloc(3 * n + 1);
|
||||
if(buf)
|
||||
for(n = 0; beg < end; n += 3)
|
||||
|
@ -287,7 +283,7 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
|
|||
|
||||
if(inlength % size)
|
||||
return -1; /* Length inconsistent with character size. */
|
||||
if(inlength / size > (CURL_SIZE_T_MAX - 1) / 4)
|
||||
if(inlength / size > (SIZE_T_MAX - 1) / 4)
|
||||
return -1; /* Too big. */
|
||||
buf = malloc(4 * (inlength / size) + 1);
|
||||
if(!buf)
|
||||
|
@ -546,7 +542,7 @@ static const char *UTime2str(const char *beg, const char *end)
|
|||
tzl, tzp);
|
||||
}
|
||||
|
||||
const char *Curl_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. */
|
||||
|
@ -605,12 +601,12 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||
Return the total string length, even if larger than `n'. */
|
||||
|
||||
for(p1 = dn->beg; p1 < dn->end;) {
|
||||
p1 = Curl_getASN1Element(&rdn, p1, dn->end);
|
||||
p1 = getASN1Element(&rdn, p1, dn->end);
|
||||
for(p2 = rdn.beg; p2 < rdn.end;) {
|
||||
p2 = Curl_getASN1Element(&atv, p2, rdn.end);
|
||||
p3 = Curl_getASN1Element(&oid, atv.beg, atv.end);
|
||||
Curl_getASN1Element(&value, p3, atv.end);
|
||||
str = Curl_ASN1tostr(&oid, 0);
|
||||
p2 = getASN1Element(&atv, p2, rdn.end);
|
||||
p3 = getASN1Element(&oid, atv.beg, atv.end);
|
||||
getASN1Element(&value, p3, atv.end);
|
||||
str = ASN1tostr(&oid, 0);
|
||||
if(!str)
|
||||
return -1;
|
||||
|
||||
|
@ -640,7 +636,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||
l++;
|
||||
|
||||
/* Generate value. */
|
||||
str = Curl_ASN1tostr(&value, 0);
|
||||
str = ASN1tostr(&value, 0);
|
||||
if(!str)
|
||||
return -1;
|
||||
for(p3 = str; *p3; p3++) {
|
||||
|
@ -655,7 +651,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
|
|||
return l;
|
||||
}
|
||||
|
||||
const char *Curl_DNtostr(curl_asn1Element *dn)
|
||||
static const char *DNtostr(curl_asn1Element *dn)
|
||||
{
|
||||
char *buf = (char *) NULL;
|
||||
ssize_t n = encodeDN(buf, 0, dn);
|
||||
|
@ -694,17 +690,17 @@ int Curl_parseX509(curl_X509certificate *cert,
|
|||
cert->certificate.end = end;
|
||||
|
||||
/* Get the sequence content. */
|
||||
if(!Curl_getASN1Element(&elem, beg, end))
|
||||
if(!getASN1Element(&elem, beg, end))
|
||||
return -1; /* Invalid bounds/size. */
|
||||
beg = elem.beg;
|
||||
end = elem.end;
|
||||
|
||||
/* Get tbsCertificate. */
|
||||
beg = Curl_getASN1Element(&tbsCertificate, beg, end);
|
||||
beg = getASN1Element(&tbsCertificate, beg, end);
|
||||
/* Skip the signatureAlgorithm. */
|
||||
beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
|
||||
beg = getASN1Element(&cert->signatureAlgorithm, beg, end);
|
||||
/* Get the signatureValue. */
|
||||
Curl_getASN1Element(&cert->signature, beg, end);
|
||||
getASN1Element(&cert->signature, beg, end);
|
||||
|
||||
/* Parse TBSCertificate. */
|
||||
beg = tbsCertificate.beg;
|
||||
|
@ -713,28 +709,28 @@ int Curl_parseX509(curl_X509certificate *cert,
|
|||
cert->version.header = NULL;
|
||||
cert->version.beg = &defaultVersion;
|
||||
cert->version.end = &defaultVersion + sizeof(defaultVersion);
|
||||
beg = Curl_getASN1Element(&elem, beg, end);
|
||||
beg = getASN1Element(&elem, beg, end);
|
||||
if(elem.tag == 0) {
|
||||
Curl_getASN1Element(&cert->version, elem.beg, elem.end);
|
||||
beg = Curl_getASN1Element(&elem, beg, end);
|
||||
getASN1Element(&cert->version, elem.beg, elem.end);
|
||||
beg = getASN1Element(&elem, beg, end);
|
||||
}
|
||||
cert->serialNumber = elem;
|
||||
/* Get signature algorithm. */
|
||||
beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
|
||||
beg = getASN1Element(&cert->signatureAlgorithm, beg, end);
|
||||
/* Get issuer. */
|
||||
beg = Curl_getASN1Element(&cert->issuer, beg, end);
|
||||
beg = getASN1Element(&cert->issuer, beg, end);
|
||||
/* Get notBefore and notAfter. */
|
||||
beg = Curl_getASN1Element(&elem, beg, end);
|
||||
ccp = Curl_getASN1Element(&cert->notBefore, elem.beg, elem.end);
|
||||
Curl_getASN1Element(&cert->notAfter, ccp, elem.end);
|
||||
beg = getASN1Element(&elem, beg, end);
|
||||
ccp = getASN1Element(&cert->notBefore, elem.beg, elem.end);
|
||||
getASN1Element(&cert->notAfter, ccp, elem.end);
|
||||
/* Get subject. */
|
||||
beg = Curl_getASN1Element(&cert->subject, beg, end);
|
||||
beg = getASN1Element(&cert->subject, beg, end);
|
||||
/* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
|
||||
beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
|
||||
ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
|
||||
beg = getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
|
||||
ccp = getASN1Element(&cert->subjectPublicKeyAlgorithm,
|
||||
cert->subjectPublicKeyInfo.beg,
|
||||
cert->subjectPublicKeyInfo.end);
|
||||
Curl_getASN1Element(&cert->subjectPublicKey, ccp,
|
||||
getASN1Element(&cert->subjectPublicKey, ccp,
|
||||
cert->subjectPublicKeyInfo.end);
|
||||
/* Get optional issuerUiqueID, subjectUniqueID and extensions. */
|
||||
cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
|
||||
|
@ -745,19 +741,19 @@ int Curl_parseX509(curl_X509certificate *cert,
|
|||
cert->extensions.header = NULL;
|
||||
cert->extensions.beg = cert->extensions.end = "";
|
||||
if(beg < end)
|
||||
beg = Curl_getASN1Element(&elem, beg, end);
|
||||
beg = getASN1Element(&elem, beg, end);
|
||||
if(elem.tag == 1) {
|
||||
cert->issuerUniqueID = elem;
|
||||
if(beg < end)
|
||||
beg = Curl_getASN1Element(&elem, beg, end);
|
||||
beg = getASN1Element(&elem, beg, end);
|
||||
}
|
||||
if(elem.tag == 2) {
|
||||
cert->subjectUniqueID = elem;
|
||||
if(beg < end)
|
||||
beg = Curl_getASN1Element(&elem, beg, end);
|
||||
beg = getASN1Element(&elem, beg, end);
|
||||
}
|
||||
if(elem.tag == 3)
|
||||
Curl_getASN1Element(&cert->extensions, elem.beg, elem.end);
|
||||
getASN1Element(&cert->extensions, elem.beg, elem.end);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -785,12 +781,12 @@ static const char *dumpAlgo(curl_asn1Element *param,
|
|||
|
||||
/* Get algorithm parameters and return algorithm name. */
|
||||
|
||||
beg = Curl_getASN1Element(&oid, beg, end);
|
||||
beg = getASN1Element(&oid, beg, end);
|
||||
param->header = NULL;
|
||||
param->tag = 0;
|
||||
param->beg = param->end = end;
|
||||
if(beg < end)
|
||||
Curl_getASN1Element(param, beg, end);
|
||||
getASN1Element(param, beg, end);
|
||||
return OID2str(oid.beg, oid.end, TRUE);
|
||||
}
|
||||
|
||||
|
@ -801,7 +797,7 @@ static void do_pubkey_field(struct Curl_easy *data, int certnum,
|
|||
|
||||
/* Generate a certificate information record for the public key. */
|
||||
|
||||
output = Curl_ASN1tostr(elem, 0);
|
||||
output = ASN1tostr(elem, 0);
|
||||
if(output) {
|
||||
if(data->set.ssl.certinfo)
|
||||
Curl_ssl_push_certinfo(data, certnum, label, output);
|
||||
|
@ -825,10 +821,10 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
|
|||
/* Generate all information records for the public key. */
|
||||
|
||||
/* Get the public key (single element). */
|
||||
Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
|
||||
getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
|
||||
|
||||
if(strcasecompare(algo, "rsaEncryption")) {
|
||||
p = Curl_getASN1Element(&elem, pk.beg, pk.end);
|
||||
p = getASN1Element(&elem, pk.beg, pk.end);
|
||||
/* Compute key length. */
|
||||
for(q = elem.beg; !*q && q < elem.end; q++)
|
||||
;
|
||||
|
@ -849,22 +845,22 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
|
|||
}
|
||||
/* Generate coefficients. */
|
||||
do_pubkey_field(data, certnum, "rsa(n)", &elem);
|
||||
Curl_getASN1Element(&elem, p, pk.end);
|
||||
getASN1Element(&elem, p, pk.end);
|
||||
do_pubkey_field(data, certnum, "rsa(e)", &elem);
|
||||
}
|
||||
else if(strcasecompare(algo, "dsa")) {
|
||||
p = Curl_getASN1Element(&elem, param->beg, param->end);
|
||||
p = getASN1Element(&elem, param->beg, param->end);
|
||||
do_pubkey_field(data, certnum, "dsa(p)", &elem);
|
||||
p = Curl_getASN1Element(&elem, p, param->end);
|
||||
p = getASN1Element(&elem, p, param->end);
|
||||
do_pubkey_field(data, certnum, "dsa(q)", &elem);
|
||||
Curl_getASN1Element(&elem, p, param->end);
|
||||
getASN1Element(&elem, p, param->end);
|
||||
do_pubkey_field(data, certnum, "dsa(g)", &elem);
|
||||
do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
|
||||
}
|
||||
else if(strcasecompare(algo, "dhpublicnumber")) {
|
||||
p = Curl_getASN1Element(&elem, param->beg, param->end);
|
||||
p = getASN1Element(&elem, param->beg, param->end);
|
||||
do_pubkey_field(data, certnum, "dh(p)", &elem);
|
||||
Curl_getASN1Element(&elem, param->beg, param->end);
|
||||
getASN1Element(&elem, param->beg, param->end);
|
||||
do_pubkey_field(data, certnum, "dh(g)", &elem);
|
||||
do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
|
||||
}
|
||||
|
@ -903,7 +899,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Subject. */
|
||||
ccp = Curl_DNtostr(&cert.subject);
|
||||
ccp = DNtostr(&cert.subject);
|
||||
if(!ccp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(data->set.ssl.certinfo)
|
||||
|
@ -913,7 +909,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
|
|||
free((char *) ccp);
|
||||
|
||||
/* Issuer. */
|
||||
ccp = Curl_DNtostr(&cert.issuer);
|
||||
ccp = DNtostr(&cert.issuer);
|
||||
if(!ccp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(data->set.ssl.certinfo)
|
||||
|
@ -937,7 +933,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
|
|||
infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
|
||||
|
||||
/* Serial number. */
|
||||
ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
|
||||
ccp = ASN1tostr(&cert.serialNumber, 0);
|
||||
if(!ccp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(data->set.ssl.certinfo)
|
||||
|
@ -958,7 +954,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
|
|||
free((char *) ccp);
|
||||
|
||||
/* Start Date. */
|
||||
ccp = Curl_ASN1tostr(&cert.notBefore, 0);
|
||||
ccp = ASN1tostr(&cert.notBefore, 0);
|
||||
if(!ccp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(data->set.ssl.certinfo)
|
||||
|
@ -968,7 +964,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
|
|||
free((char *) ccp);
|
||||
|
||||
/* Expire Date. */
|
||||
ccp = Curl_ASN1tostr(&cert.notAfter, 0);
|
||||
ccp = ASN1tostr(&cert.notAfter, 0);
|
||||
if(!ccp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(data->set.ssl.certinfo)
|
||||
|
@ -992,7 +988,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
|
|||
/* TODO: extensions. */
|
||||
|
||||
/* Signature. */
|
||||
ccp = Curl_ASN1tostr(&cert.signature, 0);
|
||||
ccp = ASN1tostr(&cert.signature, 0);
|
||||
if(!ccp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(data->set.ssl.certinfo)
|
||||
|
@ -1051,7 +1047,7 @@ static const char *checkOID(const char *beg, const char *end,
|
|||
/* Check if first ASN.1 element at `beg' is the given OID.
|
||||
Return a pointer in the source after the OID if found, else NULL. */
|
||||
|
||||
ccp = Curl_getASN1Element(&e, beg, end);
|
||||
ccp = getASN1Element(&e, beg, end);
|
||||
if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
|
||||
return (const char *) NULL;
|
||||
|
||||
|
@ -1110,19 +1106,19 @@ CURLcode Curl_verifyhost(struct connectdata *conn,
|
|||
|
||||
/* Process extensions. */
|
||||
for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) {
|
||||
p = Curl_getASN1Element(&ext, p, cert.extensions.end);
|
||||
p = getASN1Element(&ext, p, cert.extensions.end);
|
||||
/* Check if extension is a subjectAlternativeName. */
|
||||
ext.beg = checkOID(ext.beg, ext.end, sanOID);
|
||||
if(ext.beg) {
|
||||
ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
|
||||
ext.beg = getASN1Element(&elem, ext.beg, ext.end);
|
||||
/* Skip critical if present. */
|
||||
if(elem.tag == CURL_ASN1_BOOLEAN)
|
||||
ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
|
||||
ext.beg = getASN1Element(&elem, ext.beg, ext.end);
|
||||
/* Parse the octet string contents: is a single sequence. */
|
||||
Curl_getASN1Element(&elem, elem.beg, elem.end);
|
||||
getASN1Element(&elem, elem.beg, elem.end);
|
||||
/* Check all GeneralNames. */
|
||||
for(q = elem.beg; matched != 1 && q < elem.end;) {
|
||||
q = Curl_getASN1Element(&name, q, elem.end);
|
||||
q = getASN1Element(&name, q, elem.end);
|
||||
switch(name.tag) {
|
||||
case 2: /* DNS name. */
|
||||
len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
|
||||
|
@ -1162,9 +1158,9 @@ CURLcode Curl_verifyhost(struct connectdata *conn,
|
|||
/* we have to look to the last occurrence of a commonName in the
|
||||
distinguished one to get the most significant one. */
|
||||
while(q < cert.subject.end) {
|
||||
q = Curl_getASN1Element(&dn, q, cert.subject.end);
|
||||
q = getASN1Element(&dn, q, cert.subject.end);
|
||||
for(p = dn.beg; p < dn.end;) {
|
||||
p = Curl_getASN1Element(&elem, p, dn.end);
|
||||
p = getASN1Element(&elem, p, dn.end);
|
||||
/* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */
|
||||
elem.beg = checkOID(elem.beg, elem.end, cnOID);
|
||||
if(elem.beg)
|
||||
|
@ -1173,7 +1169,7 @@ CURLcode Curl_verifyhost(struct connectdata *conn,
|
|||
}
|
||||
|
||||
/* Check the CN if found. */
|
||||
if(!Curl_getASN1Element(&elem, name.beg, name.end))
|
||||
if(!getASN1Element(&elem, name.beg, name.end))
|
||||
failf(data, "SSL: unable to obtain common name from peer certificate");
|
||||
else {
|
||||
len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end);
|
||||
|
|
Loading…
Reference in New Issue