Example #1
0
Bool
CheckHostnameInCertificate(X509 *cert, const char *hostname)
{
	X509_EXTENSION *ext;
	ASN1_OBJECT *extobj;
	int ext_count, i, oid;
	Bool should_check_cn = TRUE;
	Bool ok = FALSE;
	char *cn;

	if (cert == NULL) return FALSE;
	if (strcasecmp(hostname, "localhost") == 0) return TRUE;
	if (strcasecmp(hostname, "127.0.0.1") == 0) return TRUE;
	if (strcasecmp(hostname, "::1") == 0) return TRUE;

	/* check dNSName in subjectAltName extension */
	if ((ext_count = X509_get_ext_count(cert)) > 0){
		for (i = 0; i < ext_count; i++){
			if ((ext = X509_get_ext(cert, i)) == NULL) break;
		if ((extobj = X509_EXTENSION_get_object(ext)) == NULL) break;
			if ((oid = OBJ_obj2nid(extobj)) == NID_subject_alt_name){
				ok = CheckSubjectAltName(ext, hostname);
			}
		}
	}
	/* check commonName */
	if (ok != TRUE && should_check_cn == TRUE){
		if ((cn = GetCommonNameFromCertificate(cert)) != NULL){
			if (strcasecmp(cn, hostname) == 0) ok = TRUE;
			xfree(cn);
		}
	}

	return ok;
}
Example #2
0
static PyObject *
get_all_extensions (certificate_x509 *self, PyObject *args)
{
	if (!PyArg_ParseTuple (args, "")) {
		return NULL;
	}

	int i;
	int ext_count = X509_get_ext_count (self->x509);

	char oid[MAX_BUF];
	PyObject *dict = PyDict_New ();
	for (i = 0; i < ext_count; i++) {
		X509_EXTENSION *ext = X509_get_ext (self->x509, i);

		OBJ_obj2txt (oid, MAX_BUF, ext->object, 1);
		PyObject *key = PyString_FromString (oid);

		char *value = NULL;
		size_t length =
			get_extension_by_object (self->x509, ext->object,
						 &value);

		PyObject *dict_value = PyString_FromStringAndSize (value,
								   length);
		free (value);
		PyDict_SetItem (dict, key, dict_value);

		Py_DECREF (key);
		Py_DECREF (dict_value);
	}

	return dict;
}
Example #3
0
int main(int argc, char **argv)
{
	X509 *cert;
	FILE *inf;
	int i, count;
	X509_EXTENSION *ext;
	X509V3_add_standard_extensions();
	ERR_load_crypto_strings();
	if(!argv[1]) {
		fprintf(stderr, "Usage v3prin cert.pem\n");
		exit(1);
	}
	if(!(inf = fopen(argv[1], "r"))) {
		fprintf(stderr, "Can't open %s\n", argv[1]);
		exit(1);
	}
	if(!(cert = PEM_read_X509(inf, NULL, NULL))) {
		fprintf(stderr, "Can't read certificate %s\n", argv[1]);
		ERR_print_errors_fp(stderr);
		exit(1);
	}
	fclose(inf);
	count = X509_get_ext_count(cert);
	printf("%d extensions\n", count);
	for(i = 0; i < count; i++) {
		ext = X509_get_ext(cert, i);
		printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
		if(!X509V3_EXT_print_fp(stdout, ext, 0, 0)) ERR_print_errors_fp(stderr);
		printf("\n");
		
	}
	return 0;
}
Example #4
0
int main(int argc, char **argv)
{
	LHASH *conf;
	X509 *cert;
	FILE *inf;
	char *conf_file;
	int i;
	int count;
	X509_EXTENSION *ext;
	X509V3_add_standard_extensions();
	ERR_load_crypto_strings();
	if(!argv[1]) {
		fprintf(stderr, "Usage: v3conf cert.pem [file.cnf]\n");
		exit(1);
	}
	conf_file = argv[2];
	if(!conf_file) conf_file = "test.cnf";
	conf = CONF_load(NULL, "test.cnf", NULL);
	if(!conf) {
		fprintf(stderr, "Error opening Config file %s\n", conf_file);
		ERR_print_errors_fp(stderr);
		exit(1);
	}

	inf = fopen(argv[1], "r");
	if(!inf) {
		fprintf(stderr, "Can't open certificate file %s\n", argv[1]);
		exit(1);
	}
	cert = PEM_read_X509(inf, NULL, NULL);
	if(!cert) {
		fprintf(stderr, "Error reading certificate file %s\n", argv[1]);
		exit(1);
	}
	fclose(inf);

	sk_pop_free(cert->cert_info->extensions, X509_EXTENSION_free);
	cert->cert_info->extensions = NULL;

	if(!X509V3_EXT_add_conf(conf, NULL, "test_section", cert)) {
		fprintf(stderr, "Error adding extensions\n");
		ERR_print_errors_fp(stderr);
		exit(1);
	}

	count = X509_get_ext_count(cert);
	printf("%d extensions\n", count);
	for(i = 0; i < count; i++) {
		ext = X509_get_ext(cert, i);
		printf("%s", OBJ_nid2ln(OBJ_obj2nid(ext->object)));
		if(ext->critical) printf(",critical:\n");
		else printf(":\n");
		X509V3_EXT_print_fp(stdout, ext, 0, 0);
		printf("\n");
		
	}
	return 0;
}
Example #5
0
/*
 *	Returns: 	0 if successfully matching certificate to TLSA record bytes
 *				-1 if there was no match
 */
int ca_constraint(const SSL *con, const X509 *tlsa_cert, int usage) {
	STACK_OF(X509) *cert_chain = NULL;
	cert_chain = SSL_get_peer_cert_chain(con);
	BIO_printf(b_err, "DANE ca_constraint() chain of %d length\n", 
		sk_X509_num(cert_chain));
	int ret_val;
	ret_val = 0;
	
	if (cert_chain != NULL) {
		int i;
		for (i = 0; i < sk_X509_num(cert_chain); i++) {			
			BIO_printf(b_err, "DANE ca_constraint() cert %d of %d.\n",
				i, sk_X509_num(cert_chain));
			/*
			BIO_printf(b_err, "DANE CXN Certificate\n");
			PEM_write_bio_X509(b_err, sk_X509_value(cert_chain, i));
			BIO_printf(b_err, "DANE TLSA Certificate\n");
			PEM_write_bio_X509(b_err, tlsa_cert);
			*/
			if (X509_cmp(tlsa_cert, sk_X509_value(cert_chain, i)) < 0) {
				ret_val = -1;
				BIO_printf(b_err, "DANE ca_constraint() certificates didn't match\n");
			} else {
				BIO_printf(b_err, "DANE ca_constraint() certificates matches\n");
				if (usage == 0)
					return 0;
				
				/*	For this to be a trust anchor, the following characteristics applies:
				 * 	1. Issuer name is the same as Subject name
				 * 	2. Either or both
				 *	a) the Key Usage field is set to keyCertSign (KU_KEY_CERT_SIGN)
				 *	b) the basicConstraints field has the attribute cA set to True (EXFLAG_CA)
				 */
				X509_NAME *issuer_name, *subject_name;
				issuer_name = X509_get_issuer_name(tlsa_cert);
				subject_name = X509_get_subject_name(tlsa_cert);
				
				if (X509_name_cmp(issuer_name, subject_name) == 0) {
					BIO_printf(b_err, "DANE issuer == subject\n");
					
					if (tlsa_cert->ex_flags & EXFLAG_CA) {
						BIO_printf(b_err, "DANE ca_constraint() EXFLAG_CA set\n");
						return 0;
					}
/*	Left unimplemented since I don't have a CA certificate to work with.*/
					int ext_count, j;
					ext_count = X509_get_ext_count(tlsa_cert);
					BIO_printf(b_err, "DANE ca_constraint() %d certificate extensions\n");

				} else {
					return 0;
				}
			}
		}
	}
	return ret_val;
}
Example #6
0
/*
 * post_connection_check
 */
long post_connection_check(SSL *ssl, const char *host)
{
  X509 *cert;
  X509_NAME * subj;
  char data[256];

  int extcount;
 
  if ( !(cert = SSL_get_peer_certificate(ssl)) || !host ) {
    int_error("Failed to get peer certificate or host");
    return 0; //SSL_get_verify_result(ssl);
  }

  //
  // get the extension in the certificate
  //
  if ( extcount = X509_get_ext_count(cert) > 0 ) {
    
    int i;
    for (i = 0; i < extcount; i++) {

      const char * extstr;
      X509_EXTENSION * ext;
      
      ext = X509_get_ext(cert, i);
      extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
      
      fprintf(stderr, " %s\n",extstr);
    }
    
  }// extension

  //
  // Get the CN
  //
  
  memset(data, 0, 256);
  if ((subj = X509_get_subject_name(cert)) &&
      (X509_NAME_get_text_by_NID(subj, NID_commonName, data, 256)) > 0) {
    
    time_t now;
    time(&now);

    data[255] = '\n';
    fprintf(stderr," CN = %s\n", data);
    // Record in file
    fprintf(student_file,"%s CN = %s\n", ctime(&now), data);
    // Record in db
    record_in_db(data, ctime(&now));

    fflush(student_file);
  }
  
  X509_free(cert);
  
  return SSL_get_verify_result(ssl);
}
Example #7
0
:return: Number of extensions as a Python integer\n\
";

static PyObject *
crypto_X509_get_extension_count(crypto_X509Obj *self, PyObject *args) {
    if (!PyArg_ParseTuple(args, ":get_extension_count")) {
        return NULL;
    }

    return PyLong_FromLong((long)X509_get_ext_count(self->x509));
}
Example #8
0
int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
	{
	EVP_PKEY *pk;
	int ret= -1,i,j;

	if (pkey == NULL)
		pk=X509_get_pubkey(x);
	else
		pk=pkey;
	if (pk == NULL) goto err;

	i=pk->type;
	if (i == EVP_PKEY_RSA)
		{
		ret=SSL_PKEY_RSA_ENC;
		if (x != NULL)
			{
			j=X509_get_ext_count(x);
			/* check to see if this is a signing only certificate */
			/* EAY EAY EAY EAY */
			}
		}
	else if (i == EVP_PKEY_DSA)
		{
		ret=SSL_PKEY_DSA_SIGN;
		}
	else if (i == EVP_PKEY_DH)
		{
		/* if we just have a key, we needs to be guess */

		if (x == NULL)
			ret=SSL_PKEY_DH_DSA;
		else
			{
			j=X509_get_signature_type(x);
			if (j == EVP_PKEY_RSA)
				ret=SSL_PKEY_DH_RSA;
			else if (j== EVP_PKEY_DSA)
				ret=SSL_PKEY_DH_DSA;
			else ret= -1;
			}
		}
	else
		ret= -1;

err:
	if(!pkey) EVP_PKEY_free(pk);
	return(ret);
	}
Example #9
0
IoObject *IoCertificate_extensions(IoCertificate *self, IoObject *locals, IoMessage *m)
{
	IoObject *map = IoObject_new(IoObject_state(self));
	int i;
	for(i = 0; i < X509_get_ext_count(X509(self)); i++)
	{
		IoObject *ioext = IoObject_new(IoObject_state(self));
		X509_EXTENSION *ext = X509_get_ext(X509(self), i);
		const char *key = (const char *)OBJ_nid2ln(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
		const char *value = (const char *)ASN1_STRING_data(X509_EXTENSION_get_data(ext));
		int isCritical = X509_EXTENSION_get_critical(ext);
		IoObject_setSlot_to_(ioext, IOSYMBOL("value"), IoSeq_newWithCString_(IoObject_state(self), value));
		IoObject_setSlot_to_(ioext, IOSYMBOL("isCritical"), IONUMBER(isCritical));
		IoObject_setSlot_to_(map, IOSYMBOL(key), ioext);
	}
	return map;
}
Example #10
0
int verify_cert_hostname(X509 *cert, char *hostname) {
  int                   extcount, i, j, ok = 0;
  char                  name[256];
  X509_NAME             *subj;
  const char            *extstr;
  unsigned char         *data;
  X509_EXTENSION        *ext;
  X509V3_EXT_METHOD     *meth;

  int l = strlen(hostname);
  char hostname_end[256];
  strncpy(hostname_end, hostname, sizeof(hostname_end));
  hostname_end[l+1]=hostname[l];
  hostname_end[l]='.';

  //update meĀ [WIP] - feel free to edit
  if ((extcount = X509_get_ext_count(cert)) > 0) {
    for (i = 0;  !ok && i < extcount;  i++) {
      ext = X509_get_ext(cert, i);
      extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
      if (!strcasecmp(extstr, "subjectAltName")) {
        if (!(meth = X509V3_EXT_get(ext))) break;
        data = ext->value->data;
        int i;
        if (/*i = */strstr(data, hostname) != NULL){
          //printf("dada: %d\n", i);
          if (strstr(data, hostname_end) == NULL) {
            ok = 1;
            break;
          }
        }
      }
    }
  }

  if (!ok && (subj = X509_get_subject_name(cert)) &&
      X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0) {
    name[sizeof(name) - 1] = '\0';
    if (!strcasecmp(name, hostname)) {
      ok = 1;
    }
  }

  return ok;
}
Example #11
0
PKI_X509_EXTENSION_STACK *PKI_X509_CERT_get_extensions(const PKI_X509_CERT *x) {

  PKI_X509_EXTENSION_STACK *ret = NULL;

  int i = 0;
  int ext_count = 0;

  if (!x) return NULL;

  if ((ext_count = X509_get_ext_count (x->value)) <= 0 ) return NULL;

  for ( i=0; i < ext_count; i++ ) {
    LIBPKI_X509_EXTENSION *ext = NULL;
    // PKI_X509_EXTENSION_VALUE *ext = NULL;
    PKI_X509_EXTENSION *pki_ext = NULL;
    
    if((ext = X509_get_ext ( x->value, i )) == NULL ) {
      continue;
    }

    if((pki_ext = PKI_X509_EXTENSION_new()) == NULL ) {
      PKI_log_err ( "Memory Allocation");
      continue;
    }

    if( ext->object == NULL ) {
      PKI_X509_EXTENSION_free ( pki_ext );
      continue;
    }

    pki_ext->oid = PKI_OID_dup ( ext->object );
    pki_ext->critical = ext->critical;

    if((pki_ext->value = X509V3_EXT_d2i ( ext )) == NULL ) {
      PKI_log_debug( "Extension %d -- not parsable", i);
      PKI_X509_EXTENSION_free ( pki_ext );
      continue;
    }
  }

  return ret;
}
Example #12
0
PKI_X509_EXTENSION_STACK *PKI_X509_EXTENSION_get_list ( void *x, 
						PKI_X509_DATA type ) {

	PKI_X509_EXTENSION_STACK *ret = NULL;

	int i = 0;
	int ext_count = 0;

	if (!x) return NULL;

	if ((ext_count = X509_get_ext_count (x)) <= 0 ) return NULL;

	if(( ret = PKI_STACK_X509_EXTENSION_new()) == NULL ) return NULL;

	for ( i=0; i < ext_count; i++ ) {
		PKI_X509_EXTENSION_VALUE *ext = NULL;
		PKI_X509_EXTENSION *pki_ext = NULL;
		
		if((ext = X509_get_ext ( x, i )) == NULL ) {
			continue;
		}

		if((pki_ext = PKI_X509_EXTENSION_new()) == NULL ) {
			PKI_log_err ( "Memory Allocation");
			continue;
		}

		pki_ext->oid = ext->object;
		pki_ext->critical = ext->critical;

		if((pki_ext->value = X509V3_EXT_d2i ( ext )) == NULL ) {
			PKI_log_debug( "Extension %d -- not parsable", i);
			PKI_X509_EXTENSION_free ( pki_ext );
			continue;
		}

		PKI_STACK_X509_EXTENSION_push ( ret, pki_ext );
	}

	return ret;
}
Example #13
0
/* self sign */
static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 
						CONF *conf, char *section)
	{

	EVP_PKEY *pktmp;

	pktmp = X509_get_pubkey(x);
	EVP_PKEY_copy_parameters(pktmp,pkey);
	EVP_PKEY_save_parameters(pktmp,1);
	EVP_PKEY_free(pktmp);

	if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err;
	if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err;

	/* Lets just make it 12:00am GMT, Jan 1 1970 */
	/* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
	/* 28 days to be certified */

	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
		goto err;

	if (!X509_set_pubkey(x,pkey)) goto err;
	if (clrext)
		{
		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
		}
	if (conf)
		{
		X509V3_CTX ctx;
		X509_set_version(x,2); /* version 3 certificate */
                X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
                X509V3_set_nconf(&ctx, conf);
                if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;
		}
	if (!X509_sign(x,pkey,digest)) goto err;
	return 1;
err:
	ERR_print_errors(bio_err);
	return 0;
	}
Example #14
0
static int
verify_cert_hostname(X509 *cert, char *hostname) {
  int                   extcount, i, j, ok = 0;
  char                  name[256];
  X509_NAME             *subj;
  const char            *extstr;
  CONF_VALUE            *nval;
  const unsigned char   *data;
  X509_EXTENSION        *ext;
  X509V3_EXT_METHOD     *meth;
  STACK_OF(CONF_VALUE)  *val;

  if ((extcount = X509_get_ext_count(cert)) > 0) {
    for (i = 0;  !ok && i < extcount;  i++) {
      ext = X509_get_ext(cert, i);
      extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
      if (!strcasecmp(extstr, "subjectAltName")) {
        if (!(meth = (X509V3_EXT_METHOD *)X509V3_EXT_get(ext))) break;
        data = ext->value->data;

        val = meth->i2v(meth, meth->d2i(0, &data, ext->value->length), 0);
        for (j = 0;  j < sk_CONF_VALUE_num(val);  j++) {
          nval = sk_CONF_VALUE_value(val, j);
          if (!strcasecmp(nval->name, "DNS") && !strcasecmp(nval->value, hostname)) {
            ok = 1;
            break;
          }
        }
      }
    }
  }

  if (!ok && (subj = X509_get_subject_name(cert)) &&
      X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0) {
    name[sizeof(name) - 1] = '\0';
    if (!strcasecmp(name, hostname)) ok = 1;
  }

  return ok;
}
Example #15
0
static void CheckDuplicateExtensions(X509 *x509)
{
	STACK_OF(ASN1_OBJECT) *stack = sk_ASN1_OBJECT_new(obj_cmp);

	for (int i = 0; i < X509_get_ext_count(x509); i++)
	{
		X509_EXTENSION *ext = X509_get_ext(x509, i);
		if (ext == NULL)
		{
			SetError(ERR_INVALID);
			continue;
		}
		ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext);
		if (sk_ASN1_OBJECT_find(stack, obj) >= 0)
		{
			SetError(ERR_DUPLICATE_EXTENSION);
		}
		else
		{
			sk_ASN1_OBJECT_push(stack, obj);
		}
	}
	sk_ASN1_OBJECT_free(stack);
}
Example #16
0
/*
 * Check if a x509 extension is critical
 */
static int is_x509_ext_critical(X509 *cert, int nid)
{
	X509_EXTENSION *ex;
	ASN1_OBJECT *obj;
	int n, i;

	n = X509_get_ext_count(cert);
	for (i = 0; i < n; i++) {
		ex = X509_get_ext(cert, i);
		if (!ex) {
			continue;
		}
		obj = X509_EXTENSION_get_object(ex);
		if (!obj) {
			continue;
		}
		if (OBJ_obj2nid(obj) == nid && X509_EXTENSION_get_critical(ex)) {
			debug("Certificate nid %d is critical\n", nid);
			return 1;
		}
	}

	return 0;
}
Example #17
0
static void x509v3_cache_extensions(X509 *x)
{
  BASIC_CONSTRAINTS *bs;
  PROXY_CERT_INFO_EXTENSION *pci;
  ASN1_BIT_STRING *usage;
  ASN1_BIT_STRING *ns;
  EXTENDED_KEY_USAGE *extusage;
  X509_EXTENSION *ex;
  
  int i;
  if(x->ex_flags & EXFLAG_SET) return;
#ifndef OPENSSL_NO_SHA
  X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
#endif
  /* Does subject name match issuer ? */
  if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
       x->ex_flags |= EXFLAG_SS;
  /* V1 should mean no extensions ... */
  if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
  /* Handle basic constraints */
  if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
    if(bs->ca) x->ex_flags |= EXFLAG_CA;
    if(bs->pathlen) {
      if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
            || !bs->ca) {
        x->ex_flags |= EXFLAG_INVALID;
        x->ex_pathlen = 0;
      } else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
    } else x->ex_pathlen = -1;
    BASIC_CONSTRAINTS_free(bs);
    x->ex_flags |= EXFLAG_BCONS;
  }
  /* Handle proxy certificates */
  if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
    if (x->ex_flags & EXFLAG_CA
        || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
        || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
      x->ex_flags |= EXFLAG_INVALID;
    }
    if (pci->pcPathLengthConstraint) {
      x->ex_pcpathlen =
        ASN1_INTEGER_get(pci->pcPathLengthConstraint);
    } else x->ex_pcpathlen = -1;
    PROXY_CERT_INFO_EXTENSION_free(pci);
    x->ex_flags |= EXFLAG_PROXY;
  }
  /* Handle key usage */
  if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
    if(usage->length > 0) {
      x->ex_kusage = usage->data[0];
      if(usage->length > 1) 
        x->ex_kusage |= usage->data[1] << 8;
    } else x->ex_kusage = 0;
    x->ex_flags |= EXFLAG_KUSAGE;
    ASN1_BIT_STRING_free(usage);
  }
  x->ex_xkusage = 0;
  if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
    x->ex_flags |= EXFLAG_XKUSAGE;
    for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
      switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {
        case NID_server_auth:
        x->ex_xkusage |= XKU_SSL_SERVER;
        break;

        case NID_client_auth:
        x->ex_xkusage |= XKU_SSL_CLIENT;
        break;

        case NID_email_protect:
        x->ex_xkusage |= XKU_SMIME;
        break;

        case NID_code_sign:
        x->ex_xkusage |= XKU_CODE_SIGN;
        break;

        case NID_ms_sgc:
        case NID_ns_sgc:
        x->ex_xkusage |= XKU_SGC;
        break;

        case NID_OCSP_sign:
        x->ex_xkusage |= XKU_OCSP_SIGN;
        break;

        case NID_time_stamp:
        x->ex_xkusage |= XKU_TIMESTAMP;
        break;

        case NID_dvcs:
        x->ex_xkusage |= XKU_DVCS;
        break;
      }
    }
    sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
  }

  if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
    if(ns->length > 0) x->ex_nscert = ns->data[0];
    else x->ex_nscert = 0;
    x->ex_flags |= EXFLAG_NSCERT;
    ASN1_BIT_STRING_free(ns);
  }
  x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
  x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
  for (i = 0; i < X509_get_ext_count(x); i++)
    {
    ex = X509_get_ext(x, i);
    if (!X509_EXTENSION_get_critical(ex))
      continue;
    if (!X509_supported_extension(ex))
      {
      x->ex_flags |= EXFLAG_CRITICAL;
      break;
      }
    }
  x->ex_flags |= EXFLAG_SET;
}
Example #18
0
Datum
ssl_extension_info(PG_FUNCTION_ARGS)
{
	X509	   *cert = MyProcPort->peer;
	FuncCallContext *funcctx;
	int			call_cntr;
	int			max_calls;
	MemoryContext oldcontext;
	SSLExtensionInfoContext *fctx;

	if (SRF_IS_FIRSTCALL())
	{

		TupleDesc	tupdesc;

		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/*
		 * Switch to memory context appropriate for multiple function calls
		 */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* Create a user function context for cross-call persistence */
		fctx = (SSLExtensionInfoContext *) palloc(sizeof(SSLExtensionInfoContext));

		/* Construct tuple descriptor */
		if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("function returning record called in context that cannot accept type record")));
		fctx->tupdesc = BlessTupleDesc(tupdesc);

		/* Set max_calls as a count of extensions in certificate */
		max_calls = cert != NULL ? X509_get_ext_count(cert) : 0;

		if (max_calls > 0)
		{
			/* got results, keep track of them */
			funcctx->max_calls = max_calls;
			funcctx->user_fctx = fctx;
		}
		else
		{
			/* fast track when no results */
			MemoryContextSwitchTo(oldcontext);
			SRF_RETURN_DONE(funcctx);
		}

		MemoryContextSwitchTo(oldcontext);
	}

	/* stuff done on every call of the function */
	funcctx = SRF_PERCALL_SETUP();

	/*
	 * Initialize per-call variables.
	 */
	call_cntr = funcctx->call_cntr;
	max_calls = funcctx->max_calls;
	fctx = funcctx->user_fctx;

	/* do while there are more left to send */
	if (call_cntr < max_calls)
	{
		Datum		values[3];
		bool		nulls[3];
		char	   *buf;
		HeapTuple	tuple;
		Datum		result;
		BIO		   *membuf;
		X509_EXTENSION *ext;
		ASN1_OBJECT *obj;
		int			nid;
		int			len;

		/* need a BIO for this */
		membuf = BIO_new(BIO_s_mem());
		if (membuf == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_OUT_OF_MEMORY),
					 errmsg("could not create OpenSSL BIO structure")));

		/* Get the extension from the certificate */
		ext = X509_get_ext(cert, call_cntr);
		obj = X509_EXTENSION_get_object(ext);

		/* Get the extension name */
		nid = OBJ_obj2nid(obj);
		if (nid == NID_undef)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("unknown OpenSSL extension in certificate at position %d",
							call_cntr)));
		values[0] = CStringGetTextDatum(OBJ_nid2sn(nid));
		nulls[0] = false;

		/* Get the extension value */
		if (X509V3_EXT_print(membuf, ext, 0, 0) <= 0)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("could not print extension value in certificate at position %d",
							call_cntr)));
		len = BIO_get_mem_data(membuf, &buf);
		values[1] = PointerGetDatum(cstring_to_text_with_len(buf, len));
		nulls[1] = false;

		/* Get critical status */
		values[2] = BoolGetDatum(X509_EXTENSION_get_critical(ext));
		nulls[2] = false;

		/* Build tuple */
		tuple = heap_form_tuple(fctx->tupdesc, values, nulls);
		result = HeapTupleGetDatum(tuple);

		if (BIO_free(membuf) != 1)
			elog(ERROR, "could not free OpenSSL BIO structure");

		SRF_RETURN_NEXT(funcctx, result);
	}

	/* All done */
	SRF_RETURN_DONE(funcctx);
}
Example #19
0
su_inline
int tls_post_connection_check(tport_t *self, tls_t *tls)
{
  X509 *cert;
  int extcount;
  int i, j, error;

  if (!tls) return -1;

  cert = SSL_get_peer_certificate(tls->con);
  if (!cert) {
    SU_DEBUG_7(("%s(%p): Peer did not provide X.509 Certificate.\n", 
				__func__, (void *) self));
    if (self->tp_accepted && tls->verify_incoming)
      return X509_V_ERR_CERT_UNTRUSTED;
    else if (!self->tp_accepted && tls->verify_outgoing)
      return X509_V_ERR_CERT_UNTRUSTED;
    else 
      return X509_V_OK;
  }

  tls->subjects = su_strlst_create(tls->home);
  if (!tls->subjects)
    return X509_V_ERR_OUT_OF_MEM;

  extcount = X509_get_ext_count(cert);

  /* Find matching subjectAltName.DNS */
  for (i = 0; i < extcount; i++) {
    X509_EXTENSION *ext;
    char const *name;
#if OPENSSL_VERSION_NUMBER >  0x10000000L
    const X509V3_EXT_METHOD *vp;
#else
    X509V3_EXT_METHOD *vp;
#endif
    STACK_OF(CONF_VALUE) *values;
    CONF_VALUE *value;
    void *d2i;

    ext = X509_get_ext(cert, i);
    name = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));

    if (strcmp(name, "subjectAltName") != 0)
      continue;

    vp = X509V3_EXT_get(ext); if (!vp) continue;
    d2i = X509V3_EXT_d2i(ext);
    values = vp->i2v(vp, d2i, NULL);

    for (j = 0; j < sk_CONF_VALUE_num(values); j++) {
      value = sk_CONF_VALUE_value(values, j);
      if (strcmp(value->name, "DNS") == 0)
        su_strlst_dup_append(tls->subjects, value->value);
      if (strcmp(value->name, "IP") == 0)
        su_strlst_dup_append(tls->subjects, value->value);
      else if (strcmp(value->name, "URI") == 0)
        su_strlst_dup_append(tls->subjects, value->value);
    }
  }

  {
    X509_NAME *subject;
    char name[256];

    subject = X509_get_subject_name(cert);

    if (subject) {
      if (X509_NAME_get_text_by_NID(subject, NID_commonName,
				    name, sizeof name) > 0) {
	usize_t k, N = su_strlst_len(tls->subjects);
	name[(sizeof name) - 1] = '\0';

	for (k = 0; k < N; k++)
	  if (su_casematch(su_strlst_item(tls->subjects, k), name) == 0)
	    break;

	if (k >= N)
	  su_strlst_dup_append(tls->subjects, name);
      }
    }
  }

  X509_free(cert);

  error = SSL_get_verify_result(tls->con);

  if (cert && error == X509_V_OK)
    tls->x509_verified = 1;

  if (tport_log->log_level >= 7) {
    int i, len = su_strlst_len(tls->subjects);
    for (i=0; i < len; i++)
      SU_DEBUG_7(("%s(%p): Peer Certificate Subject %i: %s\n", \
				  __func__, (void *)self, i, su_strlst_item(tls->subjects, i)));
    if (i == 0)
      SU_DEBUG_7(("%s(%p): Peer Certificate provided no usable subjects.\n",
				  __func__, (void *)self));
  }

  /* Verify incoming connections */
  if (self->tp_accepted) {
    if (!tls->verify_incoming)
      return X509_V_OK;

    if (!tls->x509_verified)
      return error;

    if (tls->verify_subj_in) {
      su_strlst_t const *subjects = self->tp_pri->pri_primary->tp_subjects;
      int i, items;

      items = subjects ? su_strlst_len(subjects) : 0;
      if (items == 0)
        return X509_V_OK;

      for (i=0; i < items; i++) {
	if (tport_subject_search(su_strlst_item(subjects, i), tls->subjects))
	  return X509_V_OK;
      }
      SU_DEBUG_3(("%s(%p): Peer Subject Mismatch (incoming connection)\n", \
				  __func__, (void *)self));

      return X509_V_ERR_CERT_UNTRUSTED;
    }
  }
  /* Verify outgoing connections */
  else {
    char const *subject = self->tp_canon;
    if (!tls->verify_outgoing)
      return X509_V_OK;

    if (!tls->x509_verified || !subject)
      return error;

    if (tls->verify_subj_out) {
      if (tport_subject_search(subject, tls->subjects))
        return X509_V_OK; /* Subject match found in verified certificate chain */
      SU_DEBUG_3(("%s(%p): Peer Subject Mismatch (%s)\n", \
				  __func__, (void *)self, subject));

      return X509_V_ERR_CERT_UNTRUSTED;
    }
  }

  return error;
}
Example #20
0
long ipfix_ssl_post_connection_check(SSL *ssl, char *host)
{
    X509      *cert;
    X509_NAME *subj;
    char      data[256];
    int       extcount;
    int       ok = 0;

    /* Checking the return from SSL_get_peer_certificate here is not strictly
     * necessary.
     */
    if (!(cert = SSL_get_peer_certificate(ssl)) || !host)
        goto err_occured;
    if ((extcount = X509_get_ext_count(cert)) > 0)
    {
        int i;

        for (i = 0;  i < extcount;  i++)
        {
            char              *extstr;
            X509_EXTENSION    *ext;

            ext = X509_get_ext(cert, i);
            extstr = (char*) OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));

            if (!strcmp(extstr, "subjectAltName"))
            {
                int                  j;
                const unsigned char  *data;
                STACK_OF(CONF_VALUE) *val;
                CONF_VALUE           *nval;
                X509V3_EXT_METHOD    *meth;
                void                 *ext_str = NULL;

                if (!(meth = X509V3_EXT_get(ext)))
                    break;
                data = ext->value->data;

#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
                if (meth->it)
                  ext_str = ASN1_item_d2i(NULL, &data, ext->value->length,
                                          ASN1_ITEM_ptr(meth->it));
                else
                  ext_str = meth->d2i(NULL, &data, ext->value->length);
#else
                ext_str = meth->d2i(NULL, &data, ext->value->length);
#endif
                val = meth->i2v(meth, ext_str, NULL);
                for (j = 0;  j < sk_CONF_VALUE_num(val);  j++)
                {
                    nval = sk_CONF_VALUE_value(val, j);
                    if (!strcmp(nval->name, "DNS") && !strcmp(nval->value, host))
                    {
                        ok = 1;
                        break;
                    }
                }
            }
            if (ok)
                break;
        }
    }

    if (!ok && (subj = X509_get_subject_name(cert)) &&
        X509_NAME_get_text_by_NID(subj, NID_commonName, data, 256) > 0)
    {
        data[255] = 0;
        if (strcasecmp(data, host) != 0)
            goto err_occured;
    }

    X509_free(cert);
    return SSL_get_verify_result(ssl);

err_occured:
    if (cert)
        X509_free(cert);
    return X509_V_ERR_APPLICATION_VERIFICATION;
}
Example #21
0
/**
 * Returns type of proxy certificate.
 * Valid values are:
 *	  NONE
 *	  CA
 *	  EEC
 *	  GT2_PROXY
 *	  RFC_PROXY
 *	  GT2_LIMITED_PROXY
 *	  RFC_LIMITED_PROXY
 *	  GT3_PROXY
 *	  GT3_LIMITED_PROXY
 */
proxy_type_t verify_type_of_proxy(X509 * cert) {
#ifdef __func__
    const char *logstr=__func__;
#else
    const char *logstr="verify_type_of_proxy";
#endif
    proxy_type_t pt = NONE;
    char * cert_subjectdn = NULL;
    char * cert_issuerdn = NULL;
    char * tail_str = NULL;
    size_t len_subject_dn;
    size_t len_issuer_dn;

    X509_EXTENSION *                    pci_ext = NULL;
    PROXYCERTINFO *                     pci = NULL;
    PROXYPOLICY *                       policy = NULL;
    ASN1_OBJECT *                       policy_lang = NULL;
    int                                 policy_nid;
    int                                 myindex = -1;

    int  i;
    char s[EXT_TEXT_LEN];

    X509_EXTENSION *ex;

    /* Is it a CA certificate */
    if (verify_x509IsCA(cert)) {
        /* verify_log (L_DEBUG, "%s: Detected CA certificate", logstr); */
        pt = CA;
        goto finalize;
    }

    /* Check by OID */
    for (i = 0; i < X509_get_ext_count(cert); ++i) {
        ex = X509_get_ext(cert, i);

        if (X509_EXTENSION_get_object(ex)) {
            OBJ_obj2txt(s, EXT_TEXT_LEN, X509_EXTENSION_get_object(ex), 1);

            if (strcmp(s, OID_RFC_PROXY) == 0) {
                pt = RFC_PROXY;

                /* Find index of OID_RFC_PROXY */
                if((myindex = X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_RFC_PROXY), -1)) != -1  &&
                    (pci_ext = X509_get_ext(cert,myindex)) && X509_EXTENSION_get_critical(pci_ext)) {
                    if((pci = X509V3_EXT_d2i(pci_ext)) == NULL) {
                        verify_error(logstr, "Can't convert DER encoded PROXYCERTINFO extension to internal form");
                        goto failure;
                    }

                    /* Pull a certificate policy from the extension, note:
		     * pci!=NULL since we've checked that */
                    if( (policy = pci->policy) == NULL) {
                        verify_error(logstr, "Can't get policy from PROXYCERTINFO extension");
                        goto failure;
                    }

                    /* Get policy language */
                    if( (policy_lang = policy->policy_language) == NULL) {
                        verify_error(logstr, "Can't get policy language from PROXYCERTINFO extension");
                        goto failure;
                    }

                    /* Lang to NID, lang's NID holds RFC Proxy type, like limited. Impersonation is the default */
                    policy_nid = OBJ_obj2nid(policy_lang);

                    if(policy_nid == OBJ_txt2nid(IMPERSONATION_PROXY_OID)) {
                        pt = RFC_PROXY;
                    } else if(policy_nid == OBJ_txt2nid(INDEPENDENT_PROXY_OID)) {
                        pt = RFC_PROXY;
                    } else if(policy_nid == OBJ_txt2nid(LIMITED_PROXY_OID)) {
                        pt = RFC_LIMITED_PROXY;
                    } else {
                        /* RFC_RESTRICTED_PROXY */
                        pt = RFC_PROXY;
                    }

                    if(X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_RFC_PROXY), myindex) != -1) {
                        verify_error(logstr, "Found more than one PCI extension");
                        goto failure;
                    }
                }
                goto finalize;
            }
            if (strcmp(s, OID_GLOBUS_PROXY_V3) == 0) {
                pt = GT3_PROXY;

                /* Find index of OID_GT3_PROXY - Don't make it search for critical extentions... VOMS doesn't set those. */
                if((myindex = X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_GLOBUS_PROXY_V3), -1)) != -1  &&
                    (pci_ext = X509_get_ext(cert,myindex))) {
                    if((pci = X509V3_EXT_d2i(pci_ext)) == NULL) {
                        verify_error(logstr, "Can't convert DER encoded PROXYCERTINFO extension to internal form");
                        goto failure;
                    }

                    /* Pull a certificate policy from the extension. Note: pci
		     * != NULL since we've checked that */
                    if( (policy = pci->policy) == NULL) {
                        verify_error(logstr, "Can't get policy from PROXYCERTINFO extension");
                        goto failure;
                    }

                    /* Get policy language */
                    if( (policy_lang = policy->policy_language) == NULL) {
                        verify_error(logstr, "Can't get policy language from PROXYCERTINFO extension");
                        goto failure;
                    }

                    /* Lang to NID, lang's NID holds RFC Proxy type, like limited. Impersonation is the default */
                    policy_nid = OBJ_obj2nid(policy_lang);

                    if(policy_nid == OBJ_txt2nid(IMPERSONATION_PROXY_OID)) {
                        pt = GT3_PROXY;
                    } else if(policy_nid == OBJ_txt2nid(INDEPENDENT_PROXY_OID)) {
                        pt = GT3_PROXY;
                    } else if(policy_nid == OBJ_txt2nid(LIMITED_PROXY_OID)) {
                        pt = GT3_LIMITED_PROXY;
                    } else {
                        /* GT3_RESTRICTED_PROXY */
                        pt = GT3_PROXY;
                    }

                    if(X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_GLOBUS_PROXY_V3), myindex) != -1) {
                        verify_error(logstr, "Found more than one PCI extension");
                        goto failure;
                    }
                }

                goto finalize;
            }
            if (strcmp(s, OID_GLOBUS_PROXY_V2) == 0) {
                pt = GT3_PROXY;

                /* Check for GT2_PROXY tail */
                if (cert_subjectdn
                    && (strlen(cert_subjectdn) > strlen("/cn=proxy"))
                    && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=proxy")])
                    && (strcasecmp(tail_str, "/cn=proxy") == 0)
                   ) {
                    /* verify_log (L_DEBUG, "%s: Detected GT2 proxy certificate", logstr); */

                    pt = GT2_PROXY;
                    goto finalize;
                }

                /* Check for GT2_LIMITED_PROXY tail */
                if (cert_subjectdn
                    && (strlen(cert_subjectdn) > strlen("/cn=limited proxy"))
                    && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=limited proxy")])
                    && (strcasecmp(tail_str, "/cn=limited proxy") == 0)
                   ) {
                    /* verify_log (L_DEBUG, "%s: Detected GT2 limited proxy certificate", logstr); */

                    pt = GT2_LIMITED_PROXY;
                    goto finalize;
                }

                verify_error(logstr, "Detected the Globus GT2 OID in the certificate, "
                                "but seems to have a malformed Subject DN: \"%s\"", cert_subjectdn);
                goto failure;
            }
        }
    }

    /* Options left: GT2_PROXY, GT2_LIMITED_PROXY, EEC */
    /* Extract Subject DN - Needs free */
    if (!(cert_subjectdn = X509_NAME_oneline (X509_get_subject_name (cert), NULL, 0))) {
        verify_error (logstr, "Error in %s: Couldn't get the subject DN from the certificate.", logstr);
        goto failure;
    }
    if (!(cert_issuerdn = X509_NAME_oneline (X509_get_issuer_name (cert), NULL, 0))) {
        verify_error (logstr, "Error in %s: Couldn't get the issuer DN from the certificate.", logstr);
        goto failure;
    }

    /* Check length of the DNs */
    len_subject_dn = strlen(cert_subjectdn);
    len_issuer_dn  = strlen(cert_issuerdn);


    /* Lower case the Subject DN */
    /* for (j = 0; j < strlen(cert_subjectdn); j++) { cert_subjectdn[j] = tolower(cert_subjectdn[j]); } */

    /* Proxies always has a longer subject_dn then a issuer_dn and
     * the issuer_dn is a substring of the subject_dn
     */
    if (   (len_issuer_dn < len_subject_dn)
        && (strncmp(cert_subjectdn, cert_issuerdn, len_issuer_dn) == 0)
       ) {
        /* Check for GT2_PROXY tail */
        if (cert_subjectdn
            && (strlen(cert_subjectdn) > strlen("/cn=proxy"))
            && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=proxy")])
            && (strcasecmp(tail_str, "/cn=proxy") == 0)
           ) {
            /* verify_log (L_DEBUG, "%s: Detected GT2 proxy certificate", logstr); */
            pt = GT2_PROXY;
            goto finalize;
        }

        /* Check for GT2_LIMITED_PROXY tail */
        if (cert_subjectdn
            && (strlen(cert_subjectdn) > strlen("/cn=limited proxy"))
            && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=limited proxy")])
            && (strcasecmp(tail_str, "/cn=limited proxy") == 0)
           ) {
            /* verify_log (L_DEBUG, "%s: Detected GT2 limited proxy certificate", logstr); */
            pt = GT2_LIMITED_PROXY;
            goto finalize;
        }

        /* Check for RFC_PROXY, without the need for OpenSSL proxy support */
        /* Method: Check if the subject_dn is long enough, grab its tail and
         * snip of the 10 characters. Then check if the 10 characters are
         * numbers. */
        if (cert_subjectdn
            && (strlen(cert_subjectdn) > strlen("/cn=0123456789"))
            && (tail_str = strrchr(cert_subjectdn, '='))
            && (tail_str = &tail_str[1])
            && (strtol(tail_str, NULL, 10))
            && (errno != ERANGE)
           ) {
            /* verify_log (L_DEBUG, "%s: Detected RFC proxy certificate", logstr); */
            pt = RFC_PROXY;
            goto finalize;
        }

        /* Don't know the type of proxy, could be an RFC proxy with
         * improper/incomplete implementation in the active OpenSSL version or
         * a mistake in the client software */
        goto failure;
    }


    /* I have no idea what else it is, so I conclude that it's an EEC */
    pt = EEC;
    goto finalize;

failure:
    /* On failure, or non-distinct selections of the certificate, indicate NONE */
    pt = NONE;
finalize:
    if (cert_subjectdn)
        free(cert_subjectdn);
    if (cert_issuerdn)
        free(cert_issuerdn);

    return pt;
}
Example #22
0
/**
 Search for a hostname match in the SubjectAlternativeNames.
*/
uint32_t
check_san (SSL *ssl, const char *hostname)
{
  X509 *cert;
  int extcount, ok = 0;
  /* What an OpenSSL mess ... */
  if (NULL == (cert = SSL_get_peer_certificate(ssl)))
  {
    die ("Getting certificate failed");
  }

  if ((extcount = X509_get_ext_count(cert)) > 0)
  {
    int i;
    for (i = 0; i < extcount; ++i)
    {
      const char *extstr;
      X509_EXTENSION *ext;
      ext = X509_get_ext(cert, i);
      extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));

      if (!strcmp(extstr, "subjectAltName"))
      {

        int j;
        void *extvalstr;
        const unsigned char *tmp;

        STACK_OF(CONF_VALUE) *val;
        CONF_VALUE *nval;
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
        const
#endif
        X509V3_EXT_METHOD *method;

        if (!(method = X509V3_EXT_get(ext)))
        {
          break;
        }

        tmp = ext->value->data;
        if (method->it)
        {
          extvalstr = ASN1_item_d2i(NULL, &tmp, ext->value->length,
                                    ASN1_ITEM_ptr(method->it));
        } else {
          extvalstr = method->d2i(NULL, &tmp, ext->value->length);
        }

        if (!extvalstr)
        {
          break;
        }

        if (method->i2v)
        {
          val = method->i2v(method, extvalstr, NULL);
          for (j = 0; j < sk_CONF_VALUE_num(val); ++j)
          {
            nval = sk_CONF_VALUE_value(val, j);
            if ((!strcasecmp(nval->name, "DNS") &&
                !strcasecmp(nval->value, hostname) ) ||
                (!strcasecmp(nval->name, "iPAddress") &&
                !strcasecmp(nval->value, hostname)))
            {
              verb ("V: subjectAltName matched: %s, type: %s", nval->value, nval->name); // We matched this; so it's safe to print
              ok = 1;
              break;
            }
            // Attempt to match subjectAltName DNS names
            if (!strcasecmp(nval->name, "DNS"))
            {
              ok = check_wildcard_match_rfc2595(hostname, nval->value);
              if (ok)
              {
                break;
              }
            }
            verb_debug ("V: subjectAltName found but not matched: %s, type: %s",
                nval->value, sanitize_string(nval->name));
          }
        }
      } else {
        verb_debug ("V: found non subjectAltName extension");
      }
      if (ok)
      {
        break;
      }
    }
  } else {
    verb_debug ("V: no X509_EXTENSION field(s) found");
  }
  X509_free(cert);
  return ok;
}
Example #23
0
extern "C" int32_t X509GetExtCount(X509* x)
{
    return X509_get_ext_count(x);
}
Example #24
0
static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
	     X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
	     int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
	{
	int ret=0;
	ASN1_INTEGER *bs=NULL;
	X509_STORE_CTX xsc;
	EVP_PKEY *upkey;

	upkey = X509_get_pubkey(xca);
	EVP_PKEY_copy_parameters(upkey,pkey);
	EVP_PKEY_free(upkey);

	if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
		{
		BIO_printf(bio_err,"Error initialising X509 store\n");
		goto end;
		}
	if (sno) bs = sno;
	else if (!(bs = load_serial(CAfile, serialfile, create)))
		goto end;

	if (!X509_STORE_add_cert(ctx,x)) goto end;

	/* NOTE: this certificate can/should be self signed, unless it was
	 * a certificate request in which case it is not. */
	X509_STORE_CTX_set_cert(&xsc,x);
	if (!reqfile && !X509_verify_cert(&xsc))
		goto end;

	if (!X509_check_private_key(xca,pkey))
		{
		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
		goto end;
		}

	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
	if (!X509_set_serialNumber(x,bs)) goto end;

	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
		goto end;

	/* hardwired expired */
	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
		goto end;

	if (clrext)
		{
		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
		}

	if (conf)
		{
		X509V3_CTX ctx2;
		X509_set_version(x,2); /* version 3 certificate */
                X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
                X509V3_set_nconf(&ctx2, conf);
                if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
		}

	if (!X509_sign(x,pkey,digest)) goto end;
	ret=1;
end:
	X509_STORE_CTX_cleanup(&xsc);
	if (!ret)
		ERR_print_errors(bio_err);
	if (!sno) ASN1_INTEGER_free(bs);
	return ret;
	}
Example #25
0
//extention to SSL_get_verify_result
int CSSLClient::PostConnectCheck(SSL *ssl, const char *pHost)
{
	X509 *cert;
	X509_NAME *subj;
	char data[256];
	int extcount;
	int ret = 0;

	do 
	{
		if (!(cert = SSL_get_peer_certificate(ssl)) || !pHost)
		{
			break;
		}
		if ((extcount = X509_get_ext_count(cert)) > 0)
		{
			int i;
			for (i = 0; i < extcount; i++)
			{
				const char *extstr;
				X509_EXTENSION *ext;
				ext = X509_get_ext(cert, i);
				extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
				if (!strcmp(extstr, SN_subject_alt_name))
				{
					int j;
					const unsigned char *pData;
					STACK_OF(CONF_VALUE) *val;
					CONF_VALUE *nval;
					const X509V3_EXT_METHOD *pExtMethod;
					if (!(pExtMethod = X509V3_EXT_get(ext)))
					{
						break;
					}
					pData = ext->value->data;
					val = pExtMethod->i2v(pExtMethod, pExtMethod->d2i(NULL, &pData, ext->value->length), NULL);
					for (j = 0; j < sk_CONF_VALUE_num(val); j++)
					{
						nval = sk_CONF_VALUE_value(val, j);
						if (!strcmp(nval->name, "DNS") && !strcmp(nval->value, pHost))
						{
							ret = 1;
							break;
						}
					}
				}
				if (ret)
				{
					break;
				}
			}//end of for(; extentcount; )
		}
		if (!ret && (subj = X509_get_subject_name(cert)) && X509_NAME_get_text_by_NID(subj, NID_commonName, data, 256) > 0)
		{
			data[255] = 0;
			if (strcmp(data, pHost) != 0)
			{
				break;
			}
		}

		X509_free(cert);
		ret = SSL_get_verify_result(ssl);
		return ret;

	} while(0);

	if (cert)
	{
		X509_free(cert);
	}
	return -1;
}
Example #26
0
File: tls.c Project: Zabrane/SPOCP
/*
 * Check that the common name matches the host name
 */
static int
check_cert_chain(conn_t * conn, SSL * ssl, ruleset_t * rs)
{
	X509           *peer;
	X509_NAME      *xn;
	static char     subject[1024];
	int             r = FALSE, extc;

	if (SSL_get_verify_result(ssl) != X509_V_OK) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"Certificate doesn't verify");
		return FALSE;
	}

	/*
	 * Check the cert chain. The chain length is automatically checked by
	 * OpenSSL when we set the verify depth in the ctx 
	 */

	peer = SSL_get_peer_certificate(ssl);
	if (!peer) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"No peer certificate");
		return TRUE;
	}

	/*
	 * check subjectaltname 
	 */

	if ((extc = X509_get_ext_count(peer)) > 0) {
		int             i;

		for (i = 0; r == FALSE && i < extc; i++) {
			X509_EXTENSION *ext;
			const char     *extstr;

			ext = X509_get_ext(peer, i);
			extstr =
			    OBJ_nid2sn(OBJ_obj2nid
				       (X509_EXTENSION_get_object(ext)));

			if (strcmp(extstr, "subjectAltName") == 0) {
				int             j;
				unsigned char  *data;
				STACK_OF(CONF_VALUE) * val;
				CONF_VALUE     *nval;
				X509V3_EXT_METHOD *meth;

				if ((meth = X509V3_EXT_get(ext)) == 0)
					break;

				data = ext->value->data;

				val =
				    meth->i2v(meth,
					      meth->d2i(NULL, &data,
							ext->value->length),
					      NULL);

				for (j = 0;
				     r == FALSE && i < sk_CONF_VALUE_num(val);
				     j++) {
					nval = sk_CONF_VALUE_value(val, j);
					if (strcasecmp(nval->name, "DNS") == 0
					    && strcasecmp(nval->value,
							  conn->sri.
							  hostname)) {
						r = TRUE;
					}
				}
			}
		}
	}

	if (r == FALSE) {
		/*
		 * Check the subject name 
		 */
		xn = X509_get_subject_name(peer);
		X509_NAME_get_text_by_NID(xn, NID_commonName, subject, 1024);
		subject[1023] = '\0';

		traceLog(LOG_DEBUG,"\"%s\" = \"%s\" ?", subject, conn->sri.hostname);
		if (strcasecmp(subject, conn->sri.hostname) == 0) {
			r = TRUE;
		}
	}

	if (r == TRUE) {
		conn->subjectDN =
		    X509_NAME_oneline(X509_get_subject_name(peer), NULL, 0);
		conn->issuerDN =
		    X509_NAME_oneline(X509_get_issuer_name(peer), NULL, 0);
	}

	X509_free(peer);

	return r;
}
Example #27
0
extern "C" int32_t CryptoNative_X509GetExtCount(X509* x)
{
    return X509_get_ext_count(x);
}