Skip to content

Commit

Permalink
Fix the X.509 parser to support multiple Relative Distinguished Names…
Browse files Browse the repository at this point in the history
… (RDN).

Certificates of this nature can be somewhat questionable as to their validity,
but for our purposes it's irrelevant and sometimes people generate certificates
this way.  So simply accept them and ignore the minor semantic difference.

* subversion/libsvn_subr/x509parse.c
  (x509_get_attribute): New function.
  (x509_get_name): Remove the code that went into x509_get_attribute() and
    iterate over the members of the RDN set.  Adjust some variables and
    comments variables to be clearer in the process.

* subversion/tests/libsvn_subr/x509-test.c
  (cert_tests): Add the cert from Chromium's test suite for this.


git-svn-id: https://svn.apache.org/repos/asf/subversion/trunk@1655919 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
breser committed Jan 30, 2015
1 parent f33d0b9 commit aed440a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 21 deletions.
66 changes: 45 additions & 21 deletions subversion/libsvn_subr/x509parse.c
Expand Up @@ -280,9 +280,6 @@ x509_get_alg(const unsigned char **p, const unsigned char *end, x509_buf * alg)
}

/*
* RelativeDistinguishedName ::=
* SET OF AttributeTypeAndValue
*
* AttributeTypeAndValue ::= SEQUENCE {
* type AttributeType,
* value AttributeValue }
Expand All @@ -292,31 +289,19 @@ x509_get_alg(const unsigned char **p, const unsigned char *end, x509_buf * alg)
* AttributeValue ::= ANY DEFINED BY AttributeType
*/
static svn_error_t *
x509_get_name(const unsigned char **p, const unsigned char *end,
x509_name * cur, apr_pool_t *result_pool)
x509_get_attribute(const unsigned char **p, const unsigned char *end,
x509_name *cur, apr_pool_t *result_pool)
{
svn_error_t *err;
ptrdiff_t len;
const unsigned char *end2;
x509_buf *oid;
x509_buf *val;

err = asn1_get_tag(p, end, &len, ASN1_CONSTRUCTED | ASN1_SET);
if (err)
return svn_error_create(SVN_ERR_X509_CERT_INVALID_NAME, err, NULL);

end2 = end;
end = *p + len;

err = asn1_get_tag(p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (err)
return svn_error_create(SVN_ERR_X509_CERT_INVALID_NAME, err, NULL);

if (*p + len != end)
{
err = svn_error_create(SVN_ERR_ASN1_LENGTH_MISMATCH, NULL, NULL);
return svn_error_create(SVN_ERR_X509_CERT_INVALID_NAME, err, NULL);
}
end = *p + len;

oid = &cur->oid;

Expand Down Expand Up @@ -360,15 +345,54 @@ x509_get_name(const unsigned char **p, const unsigned char *end,
return svn_error_create(SVN_ERR_X509_CERT_INVALID_NAME, err, NULL);
}

return SVN_NO_ERROR;
}

/*
* RelativeDistinguishedName ::=
* SET SIZE (1..MAX) OF AttributeTypeAndValue
*/
static svn_error_t *
x509_get_name(const unsigned char **p, const unsigned char *name_end,
x509_name *name, apr_pool_t *result_pool)
{
svn_error_t *err;
ptrdiff_t len;
const unsigned char *set_end;
x509_name *cur = NULL;

err = asn1_get_tag(p, name_end, &len, ASN1_CONSTRUCTED | ASN1_SET);
if (err)
return svn_error_create(SVN_ERR_X509_CERT_INVALID_NAME, err, NULL);

set_end = *p + len;

/*
* iterate until the end of the SET is reached
*/
while (*p < set_end)
{
if (!cur)
{
cur = name;
}
else
{
cur->next = apr_palloc(result_pool, sizeof(x509_name));
cur = cur->next;
}
SVN_ERR(x509_get_attribute(p, set_end, cur, result_pool));
}

/*
* recurse until end of SEQUENCE is reached
* recurse until end of SEQUENCE (name) is reached
*/
if (*p == end2)
if (*p == name_end)
return SVN_NO_ERROR;

cur->next = apr_palloc(result_pool, sizeof(x509_name));

return svn_error_trace(x509_get_name(p, end2, cur->next, result_pool));
return svn_error_trace(x509_get_name(p, name_end, cur->next, result_pool));
}

/* Retrieve the date from the X.509 cert data between *P and END in either
Expand Down
30 changes: 30 additions & 0 deletions subversion/tests/libsvn_subr/x509-test.c
Expand Up @@ -470,6 +470,36 @@ static struct x509_test cert_tests[] = {
"b.example.com",
"47fa5c76fee6e21e37def6da3746bba84a5a09bf"
},
/* X.509 certificate with multiple Relative Distinguished Names
* Borrowed form the Chromium test suite see thier bug here
* https://code.google.com/p/chromium/issues/detail?id=101009
*/
{ "MIICsDCCAhmgAwIBAgIJAO9sL1fZ/VoPMA0GCSqGSIb3DQEBBQUAMHExbzAJBgNV"
"BAYTAlVTMA8GA1UECgwIQ2hyb21pdW0wFgYKCZImiZPyLGQBGRYIQ2hyb21pdW0w"
"GgYDVQQDDBNNdWx0aXZhbHVlIFJETiBUZXN0MB0GA1UECwwWQ2hyb21pdW0gbmV0"
"X3VuaXR0ZXN0czAeFw0xMTEyMDIwMzQ3MzlaFw0xMjAxMDEwMzQ3MzlaMHExbzAJ"
"BgNVBAYTAlVTMA8GA1UECgwIQ2hyb21pdW0wFgYKCZImiZPyLGQBGRYIQ2hyb21p"
"dW0wGgYDVQQDDBNNdWx0aXZhbHVlIFJETiBUZXN0MB0GA1UECwwWQ2hyb21pdW0g"
"bmV0X3VuaXR0ZXN0czCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnSMQ7YeC"
"sOuk+0n128F7TfDtG/X48sG10oTe65SC8N6LBLfo7YYiQZlWVHEzjsFpaiv0dx4k"
"cIFbVghXAky/r5qgM1XiAGuzzFw7R27cBTC9DPlRwHArP3CiEKO3iz8i+qu9x0il"
"/9N70LcSSAu/kGLxikDbHRoM9d2SKhy2LGsCAwEAAaNQME4wHQYDVR0OBBYEFI1e"
"cfoqc7qfjmMyHF2rh9CrR6u3MB8GA1UdIwQYMBaAFI1ecfoqc7qfjmMyHF2rh9Cr"
"R6u3MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAGKwN01A47nxVHOkw"
"wFdbT8t9FFkY3pIg5meoqO3aATNaSEzkZoUljWtWgWfzr+n4ElwZBxeYv9cPurVk"
"a+wXygzWzsOzCUMKBI/aS8ijRervyvh6LpGojPGn1HttnXNLmhy+BLECs7cq6f0Z"
"hvImrEWhD5uZGlOxaZk+bFEjQHA=",
"C=US, O=Chromium, 0.9.2342.19200300.100.1.25=Chromium, "
"CN=Multivalue RDN Test, OU=Chromium net_unittests",
"2.5.4.6 2.5.4.10 0.9.2342.19200300.100.1.25 2.5.4.3 2.5.4.11",
"C=US, O=Chromium, 0.9.2342.19200300.100.1.25=Chromium, "
"CN=Multivalue RDN Test, OU=Chromium net_unittests",
"2.5.4.6 2.5.4.10 0.9.2342.19200300.100.1.25 2.5.4.3 2.5.4.11",
"2011-12-02T03:47:39.000000Z",
"2012-01-01T03:47:39.000000Z",
NULL,
"99302ca2824f585a117bb41302a388daa0519765"
},
{ NULL }
};

Expand Down

0 comments on commit aed440a

Please sign in to comment.