aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/x509asn1.c122
1 files changed, 59 insertions, 63 deletions
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index 052bcad7e..0ab077d50 100644
--- a/lib/x509asn1.c
+++ b/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);