Esempio n. 1
0
/* Read the contents of file FILENAME into *DATUM. */
static int read_to_datum(const char *filename, gnutls_datum *datum)
{
    FILE *f = fopen(filename, "r");
    ne_buffer *buf;
    char tmp[4192];
    size_t len;

    if (!f) {
        return -1;
    }

    buf = ne_buffer_ncreate(8192);
    while ((len = fread(tmp, 1, sizeof tmp, f)) > 0) {
        ne_buffer_append(buf, tmp, len);
    }

    if (!feof(f)) {
        fclose(f);
        ne_buffer_destroy(buf);
        return -1;
    }
    
    fclose(f);

    datum->size = ne_buffer_size(buf);
    datum->data = (unsigned char *)ne_buffer_finish(buf);
    return 0;
}
static int grow(void)
{
    ne_buffer *s = ne_buffer_ncreate(2);
    ON(s == NULL);
    ne_buffer_append(s, "a", 1);
    ne_buffer_grow(s, 4);
    ONCMP(s->data, "a");
    ne_buffer_destroy(s);
    return OK;
}
Esempio n. 3
0
/* Check certificate identity.  Returns zero if identity matches; 1 if
 * identity does not match, or <0 if the certificate had no identity.
 * If 'identity' is non-NULL, store the malloc-allocated identity in
 * *identity.  Logic specified by RFC 2818 and RFC 3280. */
static int check_identity(const ne_uri *server, X509 *cert, char **identity)
{
    STACK_OF(GENERAL_NAME) *names;
    int match = 0, found = 0;
    const char *hostname;
    
    hostname = server ? server->host : "";

    names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
    if (names) {
	int n;

        /* subjectAltName contains a sequence of GeneralNames */
	for (n = 0; n < sk_GENERAL_NAME_num(names) && !match; n++) {
	    GENERAL_NAME *nm = sk_GENERAL_NAME_value(names, n);
	    
            /* handle dNSName and iPAddress name extensions only. */
	    if (nm->type == GEN_DNS) {
		char *name = dup_ia5string(nm->d.ia5);
                if (identity && !found) *identity = ne_strdup(name);
		match = ne__ssl_match_hostname(name, strlen(name), hostname);
		free(name);
		found = 1;
            } 
            else if (nm->type == GEN_IPADD) {
                /* compare IP address with server IP address. */
                ne_inet_addr *ia;
                if (nm->d.ip->length == 4)
                    ia = ne_iaddr_make(ne_iaddr_ipv4, nm->d.ip->data);
                else if (nm->d.ip->length == 16)
                    ia = ne_iaddr_make(ne_iaddr_ipv6, nm->d.ip->data);
                else
                    ia = NULL;
                /* ne_iaddr_make returns NULL if address type is unsupported */
                if (ia != NULL) { /* address type was supported. */
                    char buf[128];

                    match = strcmp(hostname, 
                                   ne_iaddr_print(ia, buf, sizeof buf)) == 0;
                    found = 1;
                    ne_iaddr_free(ia);
                } else {
                    NE_DEBUG(NE_DBG_SSL, "iPAddress name with unsupported "
                             "address type (length %d), skipped.\n",
                             nm->d.ip->length);
                }
            } 
            else if (nm->type == GEN_URI) {
                char *name = dup_ia5string(nm->d.ia5);
                ne_uri uri;

                if (ne_uri_parse(name, &uri) == 0 && uri.host && uri.scheme) {
                    ne_uri tmp;

                    if (identity && !found) *identity = ne_strdup(name);
                    found = 1;

                    if (server) {
                        /* For comparison purposes, all that matters is
                         * host, scheme and port; ignore the rest. */
                        memset(&tmp, 0, sizeof tmp);
                        tmp.host = uri.host;
                        tmp.scheme = uri.scheme;
                        tmp.port = uri.port;
                        
                        match = ne_uri_cmp(server, &tmp) == 0;
                    }
                }

                ne_uri_free(&uri);
                free(name);
            }
	}
        /* free the whole stack. */
        sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
    }
    
    /* Check against the commonName if no DNS alt. names were found,
     * as per RFC3280. */
    if (!found) {
	X509_NAME *subj = X509_get_subject_name(cert);
	X509_NAME_ENTRY *entry;
	ne_buffer *cname = ne_buffer_ncreate(30);
	int idx = -1, lastidx;

	/* find the most specific commonName attribute. */
	do {
	    lastidx = idx;
	    idx = X509_NAME_get_index_by_NID(subj, NID_commonName, lastidx);
	} while (idx >= 0);
	
	if (lastidx < 0) {
            /* no commonName attributes at all. */
            ne_buffer_destroy(cname);
	    return -1;
        }

	/* extract the string from the entry */
        entry = X509_NAME_get_entry(subj, lastidx);
        if (append_dirstring(cname, X509_NAME_ENTRY_get_data(entry))) {
            ne_buffer_destroy(cname);
            return -1;
        }
        if (identity) *identity = ne_strdup(cname->data);
        match = ne__ssl_match_hostname(cname->data, cname->used - 1, hostname);
        ne_buffer_destroy(cname);
    }

    NE_DEBUG(NE_DBG_SSL, "Identity match for '%s': %s\n", hostname, 
             match ? "good" : "bad");
    return match ? 0 : 1;
}