Hello,

As this is my first opessl patch, I might have missed something.

This patch is important for those who wants to use name constraints in a CA.
Using name constraints for DNS prevents the use of an ip address in DNS
subjAltName.
The subjAltName using ipAddress solves the problem, but it was not
implemented in OpenSSL.
Mozilla NSS and Windows already implement it.

I have certain points that I'm not completely sure. In the patch, I use
X509_V_ERR_UNSUPPORTED_NAME_SYNTAX
for invalid IP format (not 4 or 16 bytes long)

Is X509_V_ERR_UNSUPPORTED_NAME_SYNTAX the right way to deal with this
situation?

Should I use X509_V_ERR_PERMITTED_VIOLATION instead and allow a following
correct IpAddress to be tested (considering that the
certificate have a correct IpAddress and a defective IpAddress (with length
not 4 or 16)?

Another doubt is in the netmask test. I applied it to the network address
as I did with the tested address.
This will implicitly convert 192.168.2.0/16 to 192.168.0.0/16. RFC does not
specify anything about the network test.

Should I do it or simply assume that name constraints is correct? i.e.:

 if ((hostptr[i] & maskptr[i]) != baseptr[i])

Or maybe test for defective CIDR (baseptr[i] & !maskptr[i]) and return
X509_V_ERR_UNSUPPORTED_NAME_SYNTAX?

I also took a look at NSS (after I submitted the patch). They use a
different aproach, with xor,
but, AFAIK, it will be equivalent to the test I applied in the patch (but
with one AND less, and maybe
more complicated to read). They also uses different loops for ipv4/ipv6 but
I prefer the single loop approach
used in the patch.

/* name contains either a 4 byte IPv4 address or a 16 byte IPv6 address.
** constraint contains an address of the same length, and a subnet mask
** of the same length.  Compare name's address to the constraint's
** address, subject to the mask.
** Return SECSuccess if they match, SECFailure if they don't.
*/
static SECStatus
compareIPaddrN2C(const SECItem *name, const SECItem *constraint)
{
    int i;
    if (name->len == 4 && constraint->len == 8) { /* ipv4 addr */
        for (i = 0; i < 4; i++) {
    if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+4])
        goto loser;
}
return SECSuccess;
    }
    if (name->len == 16 && constraint->len == 32) { /* ipv6 addr */
        for (i = 0; i < 16; i++) {
    if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+16])
        goto loser;
}
return SECSuccess;
    }
loser:
    return SECFailure;
}
Source:
https://hg.mozilla.org/projects/nss/file/f732bcb62a2e/lib/certdb/genname.c


Regards,


---
     Luiz Angelo Daros de Luca, Me.
            luizl...@gmail.com


2014-05-05 16:23 GMT-03:00 luizl...@gmail.com via RT <r...@openssl.org>:

> From: Luiz Angelo Daros de Luca <luizl...@tre-sc.gov.br>
>
> OpenSSL is able to generate a certificate with name constraints with any
> possible
> subjectAltName field. The Name Contraint example in x509v3_config(5) even
> use IP
> as an example:
>
>         nameConstraints=permitted;IP:192.168.0.0/255.255.0.0
>
> However, until now, the verify code for IP name contraints did not exist.
> Any
> check with a IP Address Name Constraint results in a "unsupported name
> constraint
> type" error.
>
> This patch implements support for IP Address Name Constraint (v4 and v6).
> This code
> validaded correcly certificates with multiple IPv4/IPv6 address checking
> against
> a CA certificate with these constraints:
>
>         permitted;IP.1=10.9.0.0/255.255.0.0
>         permitted;IP.2=10.48.0.0/255.255.0.0
>         permitted;IP.3=10.148.0.0/255.255.0.0
>         permitted;IP.4=fdc8:123f:e31f::/ffff:ffff:ffff::
>
> Signed-off-by: Luiz Angelo Daros de Luca <luizl...@gmail.com>
> ---
>  crypto/x509v3/v3_ncons.c | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>
> diff --git a/crypto/x509v3/v3_ncons.c b/crypto/x509v3/v3_ncons.c
> index a01dc64..26a6f67 100644
> --- a/crypto/x509v3/v3_ncons.c
> +++ b/crypto/x509v3/v3_ncons.c
> @@ -78,6 +78,7 @@ static int nc_dn(X509_NAME *sub, X509_NAME *nm);
>  static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
>  static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
>  static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
> +static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base);
>
>  const X509V3_EXT_METHOD v3_name_constraints = {
>         NID_name_constraints, 0,
> @@ -362,6 +363,9 @@ static int nc_match_single(GENERAL_NAME *gen,
> GENERAL_NAME *base)
>                 return nc_uri(gen->d.uniformResourceIdentifier,
>                                         base->d.uniformResourceIdentifier);
>
> +               case GEN_IPADD:
> +               return nc_ip(gen->d.iPAddress, base->d.iPAddress);
> +
>                 default:
>                 return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
>                 }
> @@ -503,3 +507,34 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING
> *base)
>         return X509_V_OK;
>
>         }
> +
> +static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base)
> +       {
> +       int hostlen, baselen, i;
> +       unsigned char *hostptr, *baseptr, *maskptr;
> +       hostptr = ip->data;
> +       hostlen = ip->length;
> +       baseptr = base->data;
> +       baselen = base->length;
> +
> +       /* Invalid if not IPv4 or IPv6 */
> +       if (! ((hostlen == 4) || (hostlen==16)) )
> +               return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
> +       if (! ((baselen == 8) || (baselen==32)) )
> +               return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
> +
> +       /* Do not match IPv4 with IPv6 */
> +       if (hostlen*2 != baselen)
> +               return X509_V_ERR_PERMITTED_VIOLATION;
> +
> +       maskptr = base->data + hostlen;
> +
> +       /* Considering possible not aligned base ipAddress */
> +       /* Not checking for wrong mask definition: i.e.: 255.0.255.0*/
> +       for (i = 0; i < hostlen; i++)
> +               if ((hostptr[i] & maskptr[i]) != (baseptr[i] & maskptr[i]))
> +                       return X509_V_ERR_PERMITTED_VIOLATION;
> +
> +       return X509_V_OK;
> +
> +       }
> --
> 1.8.4.5
>
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> Development Mailing List                       openssl-dev@openssl.org
> Automated List Manager                           majord...@openssl.org
>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to