Beispiel #1
0
static int cert_check(CLI *c, X509_STORE_CTX *callback_ctx, int preverify_ok) {
    X509_OBJECT obj;
    ASN1_BIT_STRING *local_key, *peer_key;

    if(c->opt->verify_level==SSL_VERIFY_NONE) {
        s_log(LOG_INFO, "CERT: Verification not enabled");
        return 1; /* accept connection */
    }
    if(!preverify_ok) {
        /* remote site specified a certificate, but it's not correct */
        s_log(LOG_WARNING, "CERT: Verification error: %s",
            X509_verify_cert_error_string(callback_ctx->error));
        return 0; /* reject connection */
    }
    if(c->opt->verify_use_only_my && callback_ctx->error_depth==0) {
        if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509,
                X509_get_subject_name(callback_ctx->current_cert), &obj)!=1) {
            s_log(LOG_WARNING, "CERT: Certificate not found in local repository");
            return 0; /* reject connection */
        }
        peer_key=X509_get0_pubkey_bitstr(callback_ctx->current_cert);
        local_key=X509_get0_pubkey_bitstr(obj.data.x509);
        if(!peer_key || !local_key || peer_key->length!=local_key->length ||
                memcmp(peer_key->data, local_key->data, local_key->length)) {
            s_log(LOG_WARNING, "CERT: Public keys do not match");
            return 0; /* reject connection */
        }
    }
    return 1; /* accept connection */
}
Beispiel #2
0
char   *tls_pkey_fprint(X509 *peercert, const char *mdalg)
{
    if (var_tls_bc_pkey_fprint) {
	const char *myname = "tls_pkey_fprint";
	ASN1_BIT_STRING *key;
	char   *result;

	key = X509_get0_pubkey_bitstr(peercert);
	if (key == 0)
	    msg_fatal("%s: error extracting legacy public-key fingerprint: %m",
		      myname);

	result = tls_data_fprint((char *) key->data, key->length, mdalg);
	return (result);
    } else {
	int     len;
	char   *buf;
	char   *buf2;
	char   *result;

	len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), NULL);
	buf2 = buf = mymalloc(len);
	i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), (unsigned char **) &buf2);
	if (buf2 - buf != len)
	    msg_panic("i2d_X509_PUBKEY invalid result length");

	result = tls_data_fprint(buf, len, mdalg);
	myfree(buf);
	return (result);
    }
}
Beispiel #3
0
NOEXPORT int compare_pubkeys(X509 *c1, X509 *c2) {
#if OPENSSL_VERSION_NUMBER>=0x0090700fL
    ASN1_BIT_STRING *k1=X509_get0_pubkey_bitstr(c1);
    ASN1_BIT_STRING *k2=X509_get0_pubkey_bitstr(c2);
    if(!k1 || !k2 || k1->length!=k2->length || k1->length<0 ||
            safe_memcmp(k1->data, k2->data, (size_t)k1->length)) {
        s_log(LOG_DEBUG, "CERT: Public keys do not match");
        return 0; /* reject */
    }
#else
    (void)c1; /* skip warning about unused parameter */
    (void)c2; /* skip warning about unused parameter */
#endif
    s_log(LOG_INFO, "CERT: Locally installed certificate matched");
    return 1; /* accept */
}
Beispiel #4
0
OCSP_CERTID *OCSP_cert_to_id (const EVP_MD * dgst, X509 * subject, X509 * issuer)
{
    X509_NAME *iname;

    ASN1_INTEGER *serial;

    ASN1_BIT_STRING *ikey;

#ifndef OPENSSL_NO_SHA1
    if (!dgst)
        dgst = EVP_sha1 ();
#endif
    if (subject)
    {
        iname = X509_get_issuer_name (subject);
        serial = X509_get_serialNumber (subject);
    }
    else
    {
        iname = X509_get_subject_name (issuer);
        serial = NULL;
    }
    ikey = X509_get0_pubkey_bitstr (issuer);
    return OCSP_cert_id_new (dgst, iname, ikey, serial);
}
Beispiel #5
0
int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
	     unsigned int *len)
	{
	ASN1_BIT_STRING *key;
	key = X509_get0_pubkey_bitstr(data);
	if(!key) return 0;
	return EVP_Digest(key->data, key->length, md, len, type, NULL);
	}
Beispiel #6
0
static int cert_check(CLI *c, X509_STORE_CTX *callback_ctx, int preverify_ok) {
    X509_OBJECT obj;
#if OPENSSL_VERSION_NUMBER>=0x0090700fL
    ASN1_BIT_STRING *local_key, *peer_key;
#endif
    X509 *cert;
    int depth;

    if(c->opt->verify_level<1) {
        s_log(LOG_INFO, "CERT: Verification not enabled");
        return 1; /* accept connection */
    }
    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    depth=X509_STORE_CTX_get_error_depth(callback_ctx);
    if(!preverify_ok) {
        /* remote site specified a certificate, but it's not correct */
        if(c->opt->verify_level>=4 && depth>0) {
            s_log(LOG_INFO, "CERT: Invalid CA certificate ignored");
            return 1; /* accept connection */
        } else {
            s_log(LOG_WARNING, "CERT: Verification error: %s",
                X509_verify_cert_error_string(
                    X509_STORE_CTX_get_error(callback_ctx)));
            return 0; /* reject connection */
        }
    }
    if(c->opt->verify_level>=3 && depth==0) {
        if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509,
                X509_get_subject_name(cert), &obj)!=1) {
            s_log(LOG_WARNING,
                "CERT: Certificate not found in local repository");
            return 0; /* reject connection */
        }
#if OPENSSL_VERSION_NUMBER>=0x0090700fL
        peer_key=X509_get0_pubkey_bitstr(cert);
        local_key=X509_get0_pubkey_bitstr(obj.data.x509);
        if(!peer_key || !local_key || peer_key->length!=local_key->length ||
                memcmp(peer_key->data, local_key->data, local_key->length)) {
            s_log(LOG_WARNING, "CERT: Public keys do not match");
            return 0; /* reject connection */
        }
#endif
        s_log(LOG_INFO, "CERT: Locally installed certificate matched");
    }
    return 1; /* accept connection */
}
Beispiel #7
0
static int verify_local_public_key (X509 * crt)
{
    int l;
    void *p = NULL;

    if (!cache_pkey) {
        char *cn, *cn1;
        char *fn;
        BIO *cb;
        X509 *cache_crt;

        cn = get_cn_from_crt (crt);
        if (!cn)
            return (0);

        cn1 = cn;
        if (*cn1 == '*')
            cn1++;
        if (*cn1 == '.')
            cn1++;

        fn = (char *) malloc (strlen (PBC_KEY_DIR) + strlen (cn1) + 16);
        sprintf (fn, "%s/%s.crt", PBC_KEY_DIR, cn1);

        cb = BIO_new (BIO_s_file ());

        if (BIO_read_filename (cb, fn) > 0) {
            cache_crt = PEM_read_bio_X509 (cb, NULL, NULL, NULL);
            if (cache_crt)
                cache_pkey = X509_get0_pubkey_bitstr (cache_crt);
        }
        BIO_free (cb);
        free (cn);
        free (fn);
    }

    if (cache_pkey) {
        ASN1_BIT_STRING *nkey;
        nkey = X509_get0_pubkey_bitstr (crt);
        if (nkey && (nkey->length == cache_pkey->length) &&
            (memcmp (nkey->data, cache_pkey->data, nkey->length) == 0))
            return (1);
    }
    return (0);
}
Beispiel #8
0
int X509_ocspid_print(BIO *bp, X509 *x)
{
    unsigned char *der = NULL;
    unsigned char *dertmp;
    int derlen;
    int i;
    unsigned char SHA1md[SHA_DIGEST_LENGTH];
    ASN1_BIT_STRING *keybstr;
    X509_NAME *subj;

    /*
     * display the hash of the subject as it would appear in OCSP requests
     */
    if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
        goto err;
    subj = X509_get_subject_name(x);
    derlen = i2d_X509_NAME(subj, NULL);
    if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL)
        goto err;
    i2d_X509_NAME(subj, &dertmp);

    if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
        goto err;
    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
            goto err;
    }
    OPENSSL_free(der);
    der = NULL;

    /*
     * display the hash of the public key as it would appear in OCSP requests
     */
    if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
        goto err;

    keybstr = X509_get0_pubkey_bitstr(x);

    if (keybstr == NULL)
        goto err;

    if (!EVP_Digest(ASN1_STRING_get0_data(keybstr),
                    ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(),
                    NULL))
        goto err;
    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
            goto err;
    }
    BIO_printf(bp, "\n");

    return 1;
 err:
    OPENSSL_free(der);
    return 0;
}
Beispiel #9
0
// Create a filename, based on the actual data for a certificate
char *GenerateFileName(unsigned int version_num, const byte *dercert_data, size_t dercert_len,
						BOOL with_pub_key, const DEFCERT_keyid_item *item)
{
	if(dercert_data == NULL)
		return NULL;

	char *ret = NULL;
	// Work buffer, large enough to hold the largest hash in asciiform in _XXXX form
	char *buffer = new char[((EVP_MAX_MD_SIZE+1)/2)*5+1];
	unsigned char *name = NULL;
	X509 *cert = NULL;

	if(buffer == NULL)
		return NULL;

	do
	{
		// Get the certificate
		const unsigned char *data = dercert_data;
		X509 *cert = d2i_X509(NULL, &data, dercert_len);
		if(cert == NULL)
			break;

		// buffer for name hash
		unsigned char name_hash[EVP_MAX_MD_SIZE+1]; /* ARRAY OK 2009-06-11 yngve */
		EVP_MD_CTX hash;

		// extract name
		int len = i2d_X509_NAME(X509_get_subject_name(cert), &name);
		if(name == NULL)
			break;

		// digest it
		EVP_DigestInit(&hash, EVP_sha256());
		EVP_DigestUpdate(&hash, name, len);
		if(with_pub_key)
		{
			// and if requested the public key
			ASN1_BIT_STRING *key = X509_get0_pubkey_bitstr(cert);
			if(key)
				EVP_DigestUpdate(&hash, key->data, key->length);
		}
		// and a key id
		if(item && item->keyid)
			EVP_DigestUpdate(&hash, item->keyid, item->keyid_len);

		// version number is first part of name
		name_hash[0] = version_num;
		unsigned int md_len = 0;
		// then the digest result
		EVP_DigestFinal(&hash, name_hash+1, &md_len);

		// Hexify the result
		char *id_string = buffer;
		int id_len = md_len+1, i =0;
		
		// first, version number
		if(version_num)
		{
			sprintf(id_string, "%.2X", name_hash[i]);
			id_string+=2;
		}
		// then each pair of bytes
		for(i++ ;i<id_len; i+=2, id_string+=5)
			sprintf(id_string, (i+2 < id_len ? "%.2X%.2X_" : "%.2X%.2X"), name_hash[i], name_hash[i+1]);

		char *short_name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
		if(short_name)
		{
			printf("%s\n    %s: %s\n         %s\n", short_name, (with_pub_key ? "TRUE" : "FALSE"), 
				(item == NULL ? "No dep" : "dep"), buffer);

			OPENSSL_free(short_name);
		}

		// Return in buffe
		ret = buffer;
	}while(0);

	if(name)
		OPENSSL_free(name);
	name = NULL;
	if(cert)
		X509_free(cert);
	cert = NULL;
	// If no return free buffer
	if(ret == NULL)
		delete [] buffer;
	buffer = NULL;

	return ret;
}
Beispiel #10
0
const void * PKI_X509_CERT_get_data(const PKI_X509_CERT * x,
				    PKI_X509_DATA         type) {

  const void *ret = NULL;
  LIBPKI_X509_CERT *tmp_x = NULL;

  if (!x || !x->value) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return (NULL);
  }

  tmp_x = x->value;

  switch (type)
  {
    case PKI_X509_DATA_VERSION:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      if (tmp_x->cert_info) ret = (tmp_x)->cert_info->version;
#else
      ret = (tmp_x)->cert_info.version;
#endif
      break;

    case PKI_X509_DATA_SERIAL:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      if (tmp_x->cert_info) ret = tmp_x->cert_info->serialNumber;
#else
      ret = &((tmp_x)->cert_info.serialNumber);
#endif
      // ret = X509_get_serialNumber ( (X509 *) x->value );
      break;

    case PKI_X509_DATA_SUBJECT:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      if (tmp_x->cert_info) ret = tmp_x->cert_info->subject;
#else
      ret = tmp_x->cert_info.subject;
#endif
      // ret = X509_get_subject_name( (X509 *) x->value );
      break;

    case PKI_X509_DATA_ISSUER:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      if (tmp_x->cert_info) ret = tmp_x->cert_info->issuer;
#else
      ret = tmp_x->cert_info.issuer;
#endif
      // ret = X509_get_issuer_name( (X509 *) x->value );
      break;

    case PKI_X509_DATA_NOTBEFORE:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      ret = tmp_x->cert_info->validity->notBefore;
#else
      ret = X509_get0_notBefore((X509 *)tmp_x);
#endif
      break;

    case PKI_X509_DATA_NOTAFTER:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      ret = tmp_x->cert_info->validity->notAfter;
#else
      ret = X509_get0_notAfter((X509 *)tmp_x);
#endif
      break;

    case PKI_X509_DATA_KEYPAIR_VALUE:
    case PKI_X509_DATA_PUBKEY:
      ret = X509_get_pubkey((X509 *)tmp_x);
      break;

    case PKI_X509_DATA_PUBKEY_BITSTRING:
      ret = X509_get0_pubkey_bitstr((X509 *)tmp_x);
      break;

    case PKI_X509_DATA_SIGNATURE:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      ret = (tmp_x)->signature;
#else
      ret = &(tmp_x)->signature;
#endif
      break;

    // Signature Algorithm within the certInfo structure
    case PKI_X509_DATA_ALGORITHM:
    case PKI_X509_DATA_SIGNATURE_ALG1:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      if (tmp_x->cert_info && tmp_x->cert_info->signature)
        ret = tmp_x->cert_info->signature;
#else
	ret = X509_get0_tbs_sigalg((const X509 *)x->value);
#endif
      break;

    case PKI_X509_DATA_SIGNATURE_ALG2:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      if (tmp_x->sig_alg) ret = tmp_x->sig_alg;
#else
      ret = &tmp_x->sig_alg;
#endif
      break;

    case PKI_X509_DATA_KEYSIZE:
    case PKI_X509_DATA_CERT_TYPE:
      PKI_ERROR(PKI_ERR_PARAM_TYPE, "Deprecated Cert Datatype");
      break;

/*
    case PKI_X509_DATA_KEYSIZE:
      tmp_int = PKI_Malloc ( sizeof( int ));
      *tmp_int = EVP_PKEY_size(X509_get_pubkey((X509 *)x->value));
      ret = tmp_int;
      break;

    case PKI_X509_DATA_CERT_TYPE:
      tmp_int = PKI_Malloc ( sizeof ( int ));
      *tmp_int = PKI_X509_CERT_get_type( x );
      break;
*/

    case PKI_X509_DATA_EXTENSIONS:
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      ret = tmp_x->cert_info->extensions;
#else
      ret = tmp_x->cert_info.extensions;
#endif
      break;

    default:
      /* Not Recognized/Supported DATATYPE */
      return (NULL);
  }

  return (ret);
}
Beispiel #11
0
static int openssl_ocsp_request_new(lua_State*L)
{
  OCSP_REQUEST *req = NULL;
  
  if (lua_isstring(L, 1))
  {
    BIO* bio = load_bio_object(L, 1);
    req = d2i_OCSP_REQUEST_bio(bio, NULL);
    /*
    if (!req)
    {
      BIO_reset(bio);
      req = PEM_read_bio_OCSP_REQUEST(bio, NULL, NULL);
    }
    */
    BIO_free(bio);
  }
  else
  {
    X509 *issuer = CHECK_OBJECT(1, X509, "openssl.x509");
    X509_NAME *iname = X509_get_subject_name(issuer);
    ASN1_BIT_STRING *ikey = X509_get0_pubkey_bitstr(issuer);

    OCSP_CERTID *id = NULL;
    OCSP_ONEREQ *one;
    char buf[1024];
    int nonce = lua_gettop(L) > 2 ? auxiliar_checkboolean(L, 3) : 0;
    req = OCSP_REQUEST_new();

    if (lua_istable(L, 2))
    {
      int len = lua_rawlen(L, 2);
      int i;
      for (i = 1; i <= len; i++)
      {
        lua_rawgeti(L, 2, i);
        if (auxiliar_isclass(L, "openssl.x509", -1))
        {
          X509 *cert = CHECK_OBJECT(2, X509, "openssl.x509");
          id = OCSP_cert_to_id(NULL, cert, issuer);
          one = OCSP_request_add0_id(req, id);
        }
        else
        {
          size_t len;
          char *serial = (char *)luaL_checklstring(L, -1, &len);
          ASN1_INTEGER *sno = ASN1_INTEGER_new();
          BIO* bio = BIO_new(BIO_s_mem());
          BIO_write(bio, serial, len);
          if (a2i_ASN1_INTEGER(bio, sno, buf, 1024) == 1)
          {
            id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
            one = OCSP_request_add0_id(req, id);
          };
          ASN1_INTEGER_free(sno);
          BIO_free(bio);
        }
        lua_pop(L, 1);
      }
    }
    else if (auxiliar_isclass(L, "openssl.x509", 2))
    {
      X509 *cert = CHECK_OBJECT(2, X509, "openssl.x509");
      id = OCSP_cert_to_id(NULL, cert, issuer);
      one = OCSP_request_add0_id(req, id);
    }
    else
    {
      ASN1_INTEGER *sno = ASN1_INTEGER_new();
      BIO* bio = load_bio_object(L, 2);

      if (a2i_ASN1_INTEGER(bio, sno, buf, 1024) == 1)
      {
        id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
        one = OCSP_request_add0_id(req, id);
      };
      ASN1_INTEGER_free(sno);
      BIO_free(bio);
    }
    if (nonce)
      OCSP_request_add1_nonce(req, NULL,  -1);
  }
  if(req) {
    PUSH_OBJECT(req, "openssl.ocsp_request");
  }else
    lua_pushnil(L);

  return 1;
}
Beispiel #12
0
void * PKI_X509_CERT_get_data ( PKI_X509_CERT *x, PKI_X509_DATA type ) {

	void *ret = NULL;
	PKI_X509_CERT_VALUE *tmp_x = NULL;
	PKI_MEM *mem = NULL;
	int *tmp_int = NULL;

	if( !x || !x->value ) return (NULL);

	tmp_x = x->value;

	switch (type)
	{
		case PKI_X509_DATA_VERSION:
			ret = (tmp_x)->cert_info->version;
			break;

		case PKI_X509_DATA_SERIAL:
			ret = X509_get_serialNumber ( (X509 *) x->value );
			break;

		case PKI_X509_DATA_SUBJECT:
			ret = X509_get_subject_name( (X509 *) x->value );
			break;

		case PKI_X509_DATA_ISSUER:
			ret = X509_get_issuer_name( (X509 *) x->value );
			break;

		case PKI_X509_DATA_NOTBEFORE:
			ret = X509_get_notBefore( (X509 *) x->value );
			break;

		case PKI_X509_DATA_NOTAFTER:
			ret = X509_get_notAfter( (X509 *) x->value );
			break;

		case PKI_X509_DATA_KEYPAIR_VALUE:
		case PKI_X509_DATA_PUBKEY:
			ret = X509_get_pubkey( (X509 *) x->value);
			break;

		case PKI_X509_DATA_PUBKEY_BITSTRING:
			ret = X509_get0_pubkey_bitstr( (X509 *) x->value);
			break;

		case PKI_X509_DATA_SIGNATURE:
			ret = (void *) (tmp_x)->signature;
			break;

		case PKI_X509_DATA_ALGORITHM:
		case PKI_X509_DATA_SIGNATURE_ALG1:
			if (tmp_x->cert_info && tmp_x->cert_info->signature)
				ret = tmp_x->cert_info->signature;
			break;

		case PKI_X509_DATA_SIGNATURE_ALG2:
			if (tmp_x->sig_alg) ret = tmp_x->sig_alg;
			break;

		case PKI_X509_DATA_KEYSIZE:
			tmp_int = PKI_Malloc ( sizeof( int ));
			*tmp_int = EVP_PKEY_size(
			X509_get_pubkey ( (X509 *) x->value ));
			ret = tmp_int;
			break;

		case PKI_X509_DATA_TBS_MEM_ASN1:
			if((mem = PKI_MEM_new_null()) == NULL ) break;
			mem->size = (size_t) ASN1_item_i2d ( (void *) tmp_x->cert_info, 
				&(mem->data), &X509_CINF_it );
			ret = mem;
			break;

		case PKI_X509_DATA_CERT_TYPE:
			tmp_int = PKI_Malloc ( sizeof ( int ));
			*tmp_int = PKI_X509_CERT_get_type( x );
			break;

		case PKI_X509_DATA_EXTENSIONS:
		default:
			/* Not Recognized/Supported DATATYPE */
			return (NULL);
	}

	return (ret);
}