Ejemplo n.º 1
0
void describeCertificates(SSL* ssl, bool isServer)
{
  // Resumed sessions don't necessarily have chains (not included in session ticket)
  X509 *cert = SSL_get_peer_certificate(ssl);
  if (cert == NULL) {
    fprintf(stderr,"No peer certificates.\n");
  } else {
    fprintf(stderr,"Peer certificates:\n");
    describeCertificate(0, cert);
    X509_free(cert);
    STACK_OF(X509) *certs = SSL_get_peer_cert_chain(ssl); // We don't have to free this apparently
    // Cached sessions may not have a chain
    if (certs != NULL) {
      // On server, chain doesn't include client certificate
      if (isServer) {
        for (int i = 0; i < sk_X509_num(certs); i++) {
          describeCertificate(i+1, sk_X509_value(certs,i));
        }
      } else {
        for (int i = 1; i < sk_X509_num(certs); i++) {
          describeCertificate(i, sk_X509_value(certs,i));
        }
      }
    }
    long verify_result = SSL_get_verify_result(ssl);
    if (verify_result == X509_V_OK) {
      fprintf(stderr,"Certificate OK\n");
    } else {
      // See 'man verify(1SSL)' for meanings of the codes
      fprintf(stderr,"Verification error %ld\n", verify_result);
      ERR_print_errors_fp(stderr);
    }
  }
}
Ejemplo n.º 2
0
static int openssl_ocsp_request_parse(lua_State*L)
{
  OCSP_REQUEST *req = CHECK_OBJECT(1, OCSP_REQUEST, "openssl.ocsp_request");
  int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2);
  OCSP_REQINFO *inf = req->tbsRequest;
  OCSP_SIGNATURE *sig = req->optionalSignature;

  BIO* bio = BIO_new(BIO_s_mem());
  int i, num;
  lua_newtable(L);
  AUXILIAR_SET(L, -1, "version", ASN1_INTEGER_get(inf->version), integer);
  if (inf->requestorName)
  {
    opensl_push_general_name(L, inf->requestorName, utf8);
    lua_setfield(L, -2, "requestorName");
  }
  num = sk_OCSP_ONEREQ_num(inf->requestList);
  lua_newtable(L);
  for (i = 0; i < num; i++)
  {
    OCSP_ONEREQ *one = sk_OCSP_ONEREQ_value(inf->requestList, i);
    OCSP_CERTID *a = one->reqCert;
    lua_newtable(L);
    {
      openssl_push_x509_algor(L, a->hashAlgorithm);
      lua_setfield(L, -2, "hashAlgorithm");

      PUSH_ASN1_OCTET_STRING(L, a->issuerNameHash);
      lua_setfield(L, -2, "issuerNameHash");

      PUSH_ASN1_OCTET_STRING(L, a->issuerKeyHash);
      lua_setfield(L, -2, "issuerKeyHash");

      PUSH_ASN1_INTEGER(L, a->serialNumber);
      lua_setfield(L, -2, "serialNumber");
    }
    lua_rawseti(L, -2, i + 1);
  }
  lua_setfield(L, -2, "requestList");

  if (inf->requestExtensions){
    STACK_OF(X509_EXTENSION) *extensions = sk_X509_EXTENSION_dup(inf->requestExtensions);
    PUSH_OBJECT(extensions,"openssl.stack_of_x509_extension");
    lua_setfield(L,-2, "extensions");
  }

  if (sig)
  {
    BIO_reset(bio);
    X509_signature_print(bio, sig->signatureAlgorithm, sig->signature);
    for (i = 0; i < sk_X509_num(sig->certs); i++)
    {
      X509_print(bio, sk_X509_value(sig->certs, i));
      PEM_write_bio_X509(bio, sk_X509_value(sig->certs, i));
    }
  }

  BIO_free(bio);
  return 1;
}
Ejemplo n.º 3
0
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
	{
	unsigned char *p;
	int i;
	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
	BUF_MEM *buf;

	/* TLSv1 sends a chain with nothing in it, instead of an alert */
	buf=s->init_buf;
	if (!BUF_MEM_grow_clean(buf,10))
		{
		SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
		return(0);
		}
	if (x != NULL)
		{
		X509_STORE_CTX xs_ctx;
  
		if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
  			{
  			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
  			return(0);
  			}
  
		X509_verify_cert(&xs_ctx);
		/* Don't leave errors in the queue */
		ERR_clear_error();
		for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
  			{
			x = sk_X509_value(xs_ctx.chain, i);

			if (!dtls1_add_cert_to_buf(buf, &l, x))
  				{
				X509_STORE_CTX_cleanup(&xs_ctx);
				return 0;
  				}
  			}
  		X509_STORE_CTX_cleanup(&xs_ctx);
  		}
	/* Thawte special :-) */
	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
		{
		x=sk_X509_value(s->ctx->extra_certs,i);
		if (!dtls1_add_cert_to_buf(buf, &l, x))
			return 0;
		}

	l-= (3 + DTLS1_HM_HEADER_LENGTH);

	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
	l2n3(l,p);
	l+=3;
	p=(unsigned char *)&(buf->data[0]);
	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);

	l+=DTLS1_HM_HEADER_LENGTH;
	return(l);
	}
Ejemplo n.º 4
0
NOEXPORT int cert_check_local(X509_STORE_CTX *callback_ctx) {
    X509 *cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    X509_OBJECT obj;
#if OPENSSL_VERSION_NUMBER>=0x10000000L
    STACK_OF(X509) *sk;
    int i;

    sk=X509_STORE_get1_certs(callback_ctx, X509_get_subject_name(cert));
    if(sk) {
        for(i=0; i<sk_X509_num(sk); i++)
            if(compare_pubkeys(cert, sk_X509_value(sk, i))) {
                sk_X509_pop_free(sk, X509_free);
                return 1; /* accept */
            }
        sk_X509_pop_free(sk, X509_free);
    }
#endif
    /* pre-1.0.0 API only returns a single matching certificate */
    if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509,
            X509_get_subject_name(cert), &obj)==1 &&
            compare_pubkeys(cert, obj.data.x509))
        return 1; /* accept */
    s_log(LOG_WARNING,
        "CERT: Certificate not found in local repository");
    X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REJECTED);
    return 0; /* reject */
}
Ejemplo n.º 5
0
int verify_cred(
    gss_cred_id_t                       credential)
{
    gss_cred_id_desc *                  cred_handle;
    X509 *                              cert;
    X509 *                              previous_cert;
    int                                 cert_count;

    cert_count = 1;
    cred_handle = (gss_cred_id_desc *) credential;
    
    if(cred_handle->pcd->cert_chain)
    {
        cert_count += sk_X509_num(cred_handle->pcd->cert_chain);
    }

    cert = cred_handle->pcd->ucert;
    previous_cert=NULL;
    cert_count--;

    do
    {
        if(previous_cert != NULL)
        {
            if(!X509_verify(previous_cert,X509_get_pubkey(cert)))
            {
                return 0;
            }
        }
        previous_cert = cert;
    } while(cert_count-- &&
            (cert = sk_X509_value(cred_handle->pcd->cert_chain,cert_count)));

    return 1;
}
Ejemplo n.º 6
0
/**
 * Return the chain of certificate of the peer.
 */
static int meth_getpeerchain(lua_State *L)
{
  int i;
  int idx = 1;
  int n_certs;
  X509 *cert;
  STACK_OF(X509) *certs;
  p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
  if (ssl->state != LSEC_STATE_CONNECTED) {
    lua_pushnil(L);
    lua_pushstring(L, "closed");
    return 2;
  }
  lua_newtable(L);
  if (ssl->ssl->server) {
    lsec_pushx509(L, SSL_get_peer_certificate(ssl->ssl));
    lua_rawseti(L, -2, idx++);
  }
  certs = SSL_get_peer_cert_chain(ssl->ssl);
  n_certs = sk_X509_num(certs);
  for (i = 0; i < n_certs; i++) {
    cert = sk_X509_value(certs, i);
    /* Increment the reference counting of the object. */
    /* See SSL_get_peer_certificate() source code.     */
    CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
    lsec_pushx509(L, cert);
    lua_rawseti(L, -2, idx++);
  }
  return 1;
}
Ejemplo n.º 7
0
static CURLcode sslctxfun( CURL * curl, void * sslctx, void * parm ) {

	sslctxparm * p = (sslctxparm *) parm;
	SSL_CTX * ctx = (SSL_CTX *) sslctx ;

	if ( !SSL_CTX_use_certificate( ctx,p->usercert ) ) {
		BIO_printf( p->errorbio, "SSL_CTX_use_certificate problem\n" ); goto err;
	}
	if ( !SSL_CTX_use_PrivateKey( ctx,p->pkey ) ) {
		BIO_printf( p->errorbio, "SSL_CTX_use_PrivateKey\n" ); goto err;
	}

	if ( !SSL_CTX_check_private_key( ctx ) ) {
		BIO_printf( p->errorbio, "SSL_CTX_check_private_key\n" ); goto err;
	}

	SSL_CTX_set_quiet_shutdown( ctx,1 );
	SSL_CTX_set_cipher_list( ctx,"RC4-MD5" );
	SSL_CTX_set_mode( ctx, SSL_MODE_AUTO_RETRY );

	X509_STORE_add_cert( ctx->cert_store,sk_X509_value( p->ca,sk_X509_num( p->ca ) - 1 ) );

	SSL_CTX_set_verify_depth( ctx,2 );

	SSL_CTX_set_verify( ctx,SSL_VERIFY_PEER,NULL );

	SSL_CTX_set_cert_verify_callback( ctx, ssl_app_verify_callback, parm );


	return CURLE_OK ;
err:
	ERR_print_errors( p->errorbio );
	return CURLE_SSL_CERTPROBLEM;

}
Ejemplo n.º 8
0
json::value get_cert_chain_information(boost::asio::ssl::verify_context &verifyCtx)
{
    X509_STORE_CTX *storeContext = verifyCtx.native_handle();

    STACK_OF(X509) *certStack = X509_STORE_CTX_get_chain(storeContext);

    const int numCerts = sk_X509_num(certStack);
    if (numCerts < 0)
    {
        return {};
    }
 
    json::value certChainInformation;

    for (int index = 0; index < numCerts; ++index)
    {
        X509 *cert = sk_X509_value(certStack, index);

        json::value certInformation;
        certInformation[U("Issuer")] = json::value::string(get_issuer_from_cert(cert));
        certInformation[U("Subject")] = json::value::string(get_subject_from_cert(cert));
        certInformation[U("FingerPrint")] = json::value::string(get_fingerprint_from_cert(cert));

        utility::stringstream_t countInfo;
        countInfo << "Certificate: " << index;
        certChainInformation[countInfo.str()] = certInformation;
    }
    return certChainInformation;
}
Ejemplo n.º 9
0
bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const
{
  // can we check the certificate against a list of fingerprints?
  if (!fingerprints_.empty()) {
    X509_STORE_CTX *sctx = ctx.native_handle();
    if (!sctx)
    {
      MERROR("Error getting verify_context handle");
      return false;
    }

    X509* cert = nullptr;
    const STACK_OF(X509)* chain = X509_STORE_CTX_get_chain(sctx);
    if (!chain || sk_X509_num(chain) < 1 || !(cert = sk_X509_value(chain, 0)))
    {
      MERROR("No certificate found in verify_context");
      return false;
    }

    // buffer for the certificate digest and the size of the result
    std::vector<uint8_t> digest(EVP_MAX_MD_SIZE);
    unsigned int size{ 0 };

    // create the digest from the certificate
    if (!X509_digest(cert, EVP_sha256(), digest.data(), &size)) {
      MERROR("Failed to create certificate fingerprint");
      return false;
    }

    // strip unnecessary bytes from the digest
    digest.resize(size);

    return std::binary_search(fingerprints_.begin(), fingerprints_.end(), digest);
  }
Ejemplo n.º 10
0
// Verify the signed block, the first 32 bytes of the data must be the certificate hash to work.
int __fastcall util_verify(char* signature, int signlen, struct util_cert* cert, char** data)
{
	unsigned int size, r;
	BIO *out = NULL;
	PKCS7 *message = NULL;
	char* data2 = NULL;
	char hash[UTIL_HASHSIZE];
	STACK_OF(X509) *st = NULL;

	cert->x509 = NULL;
	cert->pkey = NULL;
	*data = NULL;
	message = d2i_PKCS7(NULL, (const unsigned char**)&signature, signlen);
	if (message == NULL) goto error;
	out = BIO_new(BIO_s_mem());

	// Lets rebuild the original message and check the size
	size = i2d_PKCS7(message, NULL);
	if (size < (unsigned int)signlen) goto error;

	// Check the PKCS7 signature, but not the certificate chain.
	r = PKCS7_verify(message, NULL, NULL, NULL, out, PKCS7_NOVERIFY);
	if (r == 0) goto error;

	// If data block contains less than 32 bytes, fail.
	size = BIO_get_mem_data(out, &data2);
	if (size <= UTIL_HASHSIZE) goto error;

	// Copy the data block
	*data = (char*)malloc(size + 1);
	if (*data == NULL) goto error;
	memcpy(*data, data2, size);
	(*data)[size] = 0;

	// Get the certificate signer
	st = PKCS7_get0_signers(message, NULL, PKCS7_NOVERIFY);
	cert->x509 = X509_dup(sk_X509_value(st, 0));
	sk_X509_free(st);

	// Get a full certificate hash of the signer
	r = UTIL_HASHSIZE;
	X509_digest(cert->x509, EVP_sha256(), (unsigned char*)hash, &r);

	// Check certificate hash with first 32 bytes of data.
	if (memcmp(hash, *data, UTIL_HASHSIZE) != 0) goto error;

	// Approved, cleanup and return.
	BIO_free(out);
	PKCS7_free(message);

	return size;

error:
	if (out != NULL) BIO_free(out);
	if (message != NULL) PKCS7_free(message);
	if (*data != NULL) free(*data);
	if (cert->x509 != NULL) { X509_free(cert->x509); cert->x509 = NULL; }

	return 0;
}
Ejemplo n.º 11
0
static int check_signer_name(CMS_ContentInfo *cms, const char *name)
{
	STACK_OF(CMS_SignerInfo) *infos = CMS_get0_SignerInfos(cms);
	STACK_OF(X509) *crts;
	int i, ret = 1;

	if ((name == NULL) || (name[0] == '\0'))
		return 0;

	crts = CMS_get1_certs(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(infos); ++i) {
		CMS_SignerInfo *si = sk_CMS_SignerInfo_value(infos, i);
		int j;

		for (j = 0; j < sk_X509_num(crts); ++j) {
			X509 *crt = sk_X509_value(crts, j);

			if (CMS_SignerInfo_cert_cmp(si, crt) == 0) {
				ret = check_common_name(
					X509_get_subject_name(crt), name);
			}
		}
	}
	sk_X509_pop_free(crts, X509_free);

	return ret;
}
Ejemplo n.º 12
0
static VALUE
ossl_x509stctx_get_chain(VALUE self)
{
    X509_STORE_CTX *ctx;
    STACK_OF(X509) *chain;
    X509 *x509;
    int i, num;
    VALUE ary;

    GetX509StCtx(self, ctx);
    if((chain = X509_STORE_CTX_get_chain(ctx)) == NULL){
        return Qnil;
    }
    if((num = sk_X509_num(chain)) < 0){
	OSSL_Debug("certs in chain < 0???");
	return rb_ary_new();
    }
    ary = rb_ary_new2(num);
    for(i = 0; i < num; i++) {
	x509 = sk_X509_value(chain, i);
	rb_ary_push(ary, ossl_x509_new(x509));
    }

    return ary;
}
Ejemplo n.º 13
0
static int ssl_check_certificate (CONNECTION *conn, sslsockdata *data)
{
        int i, preauthrc, chain_len;
        STACK_OF(X509) *chain;
        X509 *cert;

        if ((preauthrc = ssl_check_preauth (data->cert, conn->account.host)) > 0)
                return preauthrc;

        chain = SSL_get_peer_cert_chain (data->ssl);
        chain_len = sk_X509_num (chain);
/* negative preauthrc means the certificate won't be accepted without
 * manual override. */
        if (preauthrc < 0 || !chain || (chain_len <= 1))
                return interactive_check_cert (data->cert, 0, 0);

/* check the chain from root to peer. */
        for (i = chain_len-1; i >= 0; i--) {
                cert = sk_X509_value (chain, i);

/* if the certificate validates or is manually accepted, then add it to
 * the trusted set and recheck the peer certificate */
                if (ssl_check_preauth (cert, NULL)
                || interactive_check_cert (cert, i, chain_len)) {
                        ssl_cache_trusted_cert (cert);
                        if (ssl_check_preauth (data->cert, conn->account.host))
                                return 1;
                }
        }

        return 0;
}
Ejemplo n.º 14
0
static PyObject *
ssl_Connection_get_peer_cert_chain(ssl_ConnectionObj *self, PyObject *args) {
    STACK_OF(X509) *sk;
    PyObject *chain;
    crypto_X509Obj *cert;
    Py_ssize_t i;

    if (!PyArg_ParseTuple(args, ":get_peer_cert_chain")) {
        return NULL;
    }

    sk = SSL_get_peer_cert_chain(self->ssl);
    if (sk != NULL) {
        chain = PyList_New(sk_X509_num(sk));
        for (i = 0; i < sk_X509_num(sk); i++) {
            cert = new_x509(sk_X509_value(sk, i), 1);
            if (!cert) {
                /* XXX Untested */
                Py_DECREF(chain);
                return NULL;
            }
            CRYPTO_add(&cert->x509->references, 1, CRYPTO_LOCK_X509);
            PyList_SET_ITEM(chain, i, (PyObject *)cert);
        }
        return chain;
    } else {
        Py_INCREF(Py_None);
        return Py_None;
    }

}
Ejemplo n.º 15
0
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
{
	int i, j;

	/*
	 * Preverify checks the platform's certificate store; don't
	 * allow any chain that doesn't already validate according to
	 * that.
	 */
	if (!preverify_ok)
		return 0;

	/* check each certificate in the chain against our built-in pinlist. */
	STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(ctx);
	if (!chain)
		die("No certificate chain available");

	bool found = false;
	for (i=0; i < sk_X509_num(chain); i++) {
		_cleanup_free_ char *spki_hash = NULL;
		spki_hash = hash_subject_pubkey_info(sk_X509_value(chain, i));
		if (!spki_hash)
			continue;

		for (j=0; j < (int) ARRAY_SIZE(PK_PINS); j++) {
			if (strcmp(PK_PINS[j], spki_hash) == 0) {
				found = true;
				break;
			}
		}
	}

	return found;
}
Ejemplo n.º 16
0
// success of certificates extraction
bool pemData(X509_STORE_CTX* ctx, ListHashSet<String>& certificates)
{
    bool ok = true;
    STACK_OF(X509)* certs = X509_STORE_CTX_get1_chain(ctx);
    for (int i = 0; i < sk_X509_num(certs); i++) {
        X509* uCert = sk_X509_value(certs, i);
        BIO* bio = BIO_new(BIO_s_mem());
        int res = PEM_write_bio_X509(bio, uCert);
        if (!res) {
            ok = false;
            BIO_free(bio);
            break;
        }

        unsigned char* certificateData;
        long length = BIO_get_mem_data(bio, &certificateData);
        if (length < 0) {
            ok = false;
            BIO_free(bio);
            break;
        }

        certificateData[length] = '\0';
        String certificate = certificateData;
        certificates.add(certificate);
        BIO_free(bio);
    }
        sk_X509_pop_free(certs, X509_free);
        return ok;
}
Ejemplo n.º 17
0
static int verify_certificate_chain(X509_STORE_CTX * x509_ctx, void * ignored) {
    qeo_platform_custom_certificate_validator custom_cert_validator_cb = qeo_platform_get_custom_certificate_validator();
    qeo_der_certificate certificate_chain[10];
    BIO* bios[10];
    int rc = 0;

    /** We need access to unchecked chain of certificates
     * No obvious API is found to get a hold of it. The API's available to get certificates
     * expect to do the verification first and only then you can get the chain.
     * As we want to do the validation ourselves, we just pull them out the struct to get
     * the untrusted chain.
     */
    STACK_OF(X509) *sk = x509_ctx->untrusted;

    if (sk) {
        //Lets check the stack.
        qeo_util_retcode_t retcode = QEO_UTIL_EFAIL;
        int certs = sk_X509_num(sk);
        int i;

        if (certs > 10) { //to many certificates;
            //there is also a limit of 10 in openssl for the maximum certificate chain length. We should not hit this; Still better safe then sorry.
            return 0;
        }
        memset(bios, 0, sizeof(BIO*) * 10);
        for (i = 0; i < certs ; i++) {
            int result;
            X509* cert = sk_X509_value(sk, i);
            //create a memory BIO
            BIO *mem = BIO_new(BIO_s_mem());
            if (NULL == mem) {
                goto out; //failed to create BIO
            }
            bios[i] = mem;
            //write to bio int i2d_X509_bio(BIO *bp, X509 *x);
            result = i2d_X509_bio(mem, cert);

            if (result < 0) {
                qeo_log_e("Failed to write certificate data to mem bio %d\n", result);
                goto out;
            }
            // add to array
            certificate_chain[i].size = BIO_get_mem_data(mem, &certificate_chain[i].cert_data);
        }
        //call the callback
        retcode = custom_cert_validator_cb(certificate_chain, certs);
        if (retcode == QEO_UTIL_OK) {
            rc = 1;
        } else {
            qeo_log_e("Custom certificate verification callback returned %d - Treating this as a verification error\n", retcode);
        }
out:
        //free memory
        for (i = 0; i < certs ; i++) {
            if (bios[i])
               BIO_vfree(bios[i]); //we take the void version; not much we can do if the free fails
        }
    }
    return rc;
}
Ejemplo n.º 18
0
/**
 * Adds all subjects in a PKCS12 files and notifies the frontend of them.
 */
static TokenError _backend_addFile(Backend *backend,
                                   const char *data, size_t length,
                                   void *tag) {
    SharedPKCS12 *p12 = pkcs12_parse(data, length);
    if (!p12) return TokenError_BadFile;
    
    STACK_OF(X509) *certList = pkcs12_listCerts(p12->data);
    if (!certList) return TokenError_Unknown;
    
    int certCount = sk_X509_num(certList);
    for (int i = 0; i < certCount; i++) {
        X509 *x = sk_X509_value(certList, i);
        
        if (!certutil_hasKeyUsage(x, backend->notifier->keyUsage)) goto dontAddCert;
        
        X509_NAME *id = X509_get_subject_name(x);
        if (!certutil_matchSubjectFilter(backend->notifier->subjectFilter, id))
            goto dontAddCert;
        
        PKCS12Token *token = createToken(backend, p12, id, tag);
        if (token) {
            backend->notifier->notifyFunction((Token*)token, TokenChange_Added);
            continue;
        }
        
      dontAddCert:
        X509_free(x);
    }
    
    pkcs12_release(p12);
    return TokenError_Success;
}
Ejemplo n.º 19
0
/*
 * call-seq:
 *    ssl.peer_cert_chain => [cert, ...] or nil
 */
static VALUE
ossl_ssl_get_peer_cert_chain(VALUE self)
{
    SSL *ssl;
    STACK_OF(X509) *chain;
    X509 *cert;
    VALUE ary;
    int i, num;

    Data_Get_Struct(self, SSL, ssl);
    if(!ssl){
	rb_warning("SSL session is not started yet.");
	return Qnil;
    }
    chain = SSL_get_peer_cert_chain(ssl);
    if(!chain) return Qnil;
    num = sk_X509_num(chain);
    ary = rb_ary_new2(num);
    for (i = 0; i < num; i++){
	cert = sk_X509_value(chain, i);
	rb_ary_push(ary, ossl_x509_new(cert));
    }

    return ary;
}
Ejemplo n.º 20
0
Settings::KeyPair CertWizard::importCert(QByteArray data, const QString &pw) {
	X509 *x509 = NULL;
	EVP_PKEY *pkey = NULL;
	PKCS12 *pkcs = NULL;
	BIO *mem = NULL;
	STACK_OF(X509) *certs = NULL;
	Settings::KeyPair kp;
	int ret = 0;

	mem = BIO_new_mem_buf(data.data(), data.size());
	Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE));
	pkcs = d2i_PKCS12_bio(mem, NULL);
	if (pkcs) {
		ret = PKCS12_parse(pkcs, NULL, &pkey, &x509, &certs);
		if (pkcs && !pkey && !x509 && ! pw.isEmpty()) {
			if (certs) {
				if (ret)
					sk_X509_free(certs);
				certs = NULL;
			}
			ret = PKCS12_parse(pkcs, pw.toUtf8().constData(), &pkey, &x509, &certs);
		}
		if (pkey && x509 && X509_check_private_key(x509, pkey)) {
			unsigned char *dptr;
			QByteArray key, crt;

			key.resize(i2d_PrivateKey(pkey, NULL));
			dptr=reinterpret_cast<unsigned char *>(key.data());
			i2d_PrivateKey(pkey, &dptr);

			crt.resize(i2d_X509(x509, NULL));
			dptr=reinterpret_cast<unsigned char *>(crt.data());
			i2d_X509(x509, &dptr);

			QSslCertificate qscCert = QSslCertificate(crt, QSsl::Der);
			QSslKey qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);

			QList<QSslCertificate> qlCerts;
			qlCerts << qscCert;

			if (certs) {
				for (int i=0;i<sk_X509_num(certs);++i) {
					X509 *c = sk_X509_value(certs, i);

					crt.resize(i2d_X509(c, NULL));
					dptr=reinterpret_cast<unsigned char *>(crt.data());
					i2d_X509(c, &dptr);

					QSslCertificate cert = QSslCertificate(crt, QSsl::Der);
					qlCerts << cert;
				}
			}
			bool valid = ! qskKey.isNull();
			foreach(const QSslCertificate &cert, qlCerts)
				valid = valid && ! cert.isNull();
			if (valid)
				kp = Settings::KeyPair(qlCerts, qskKey);
		}
	}
Ejemplo n.º 21
0
/* Open the inner, decrypted PKCS7 and try to write cert.  */ 
void
write_other_cert(struct scep *s) {
	PKCS7			*p7;
	STACK_OF(X509)		*certs;
	X509			*cert = NULL;
	FILE			*fp;
	int			i;

	othercert = NULL;

	/* Get certs */
	p7 = s->reply_p7;
	certs = p7->d.sign->cert;
	
	/* Find cert */
	for (i = 0; i < sk_X509_num(certs); i++) {
		char buffer[1024];

		cert = sk_X509_value(certs, i);
		if (v_flag) {
			printf("%s: found certificate with\n"
				"  subject: %s\n", pname,
				X509_NAME_oneline(X509_get_subject_name(cert),
					buffer, sizeof(buffer)));
			printf("  issuer: %s\n", 
				X509_NAME_oneline(X509_get_issuer_name(cert),
					buffer, sizeof(buffer)));
		}
		/* The serial has to match to requested one */
		if (!ASN1_INTEGER_cmp(X509_get_serialNumber(cert),
				s->ias_getcert->serial)) {
				othercert = cert;	
				break;
		}	
	}
	if (othercert == NULL) {
		fprintf(stderr, "%s: cannot find certificate\n", pname);
		exit (SCEP_PKISTATUS_FILE);

	}
	/* Write PEM-formatted file: */
	if (!(fp = fopen(w_char, "w"))) {
		fprintf(stderr, "%s: cannot open cert file for writing\n",
				pname);
		exit (SCEP_PKISTATUS_FILE);
	}
	if (v_flag)
		printf("%s: writing cert\n", pname);
	if (d_flag)
		PEM_write_X509(stdout, othercert);
	if (PEM_write_X509(fp, othercert) != 1) {
		fprintf(stderr, "%s: error while writing certificate "
			"file\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_FILE);
	}
	printf("%s: certificate written as %s\n", pname, w_char);
	(void)fclose(fp);
}
int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags)
        {
	int i;
	long l;
	OCSP_CERTID* cid = NULL;
	OCSP_ONEREQ *one = NULL;
	OCSP_REQINFO *inf = o->tbsRequest;
	OCSP_SIGNATURE *sig = o->optionalSignature;

	if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err;
	l=ASN1_INTEGER_get(inf->version);
	if (BIO_printf(bp,"    Version: %lu (0x%lx)",l+1,l) <= 0) goto err;
	if (inf->requestorName != NULL)
	        {
		if (BIO_write(bp,"\n    Requestor Name: ",21) <= 0) 
		        goto err;
		GENERAL_NAME_print(bp, inf->requestorName);
		}
	if (BIO_write(bp,"\n    Requestor List:\n",21) <= 0) goto err;
	for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++)
	        {
		one = sk_OCSP_ONEREQ_value(inf->requestList, i);
		cid = one->reqCert;
		ocsp_certid_print(bp, cid, 8);
		if (!X509V3_extensions_print(bp,
					"Request Single Extensions",
					one->singleRequestExtensions, flags, 8))
							goto err;
		}
	if (!X509V3_extensions_print(bp, "Request Extensions",
			inf->requestExtensions, flags, 4))
							goto err;
	if (sig)
	        {
		X509_signature_print(bp, sig->signatureAlgorithm, sig->signature);
		for (i=0; i<sk_X509_num(sig->certs); i++)
			{
			X509_print(bp, sk_X509_value(sig->certs,i));
			PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i));
			}
		}
	return 1;
err:
	return 0;
	}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
pki_x509 *pki_pkcs7::getCert(int x)
{
	pki_x509 *cert;
	cert = new pki_x509(X509_dup(sk_X509_value(getCertStack(), x)));
	openssl_error();
	cert->autoIntName();
	cert->pkiSource = imported;
	return cert;
}
Ejemplo n.º 25
0
int GTPublicationsFile_getSigningCert(
		const GTPublicationsFile *publications_file,
		unsigned char **cert_der, size_t *cert_der_length)
{
	int res = GT_UNKNOWN_ERROR;
	unsigned char *i2dp;
	unsigned char *tmp_der = NULL;
	int tmp_der_len;
	X509 *signing_cert = NULL;
	STACK_OF(X509) *certs = NULL;

	if (publications_file == NULL || publications_file->signature == NULL ||
			cert_der == NULL || cert_der_length == NULL) {
		res = GT_INVALID_ARGUMENT;
		goto cleanup;
	}

	certs = PKCS7_get0_signers(publications_file->signature, NULL, 0);
	if (certs == NULL) {
		res = GT_INVALID_FORMAT;
		goto cleanup;
	}

	if (sk_X509_num(certs) != 1) {
		res = GT_INVALID_FORMAT;
		goto cleanup;
	}

	signing_cert = sk_X509_value(certs, 0);

	tmp_der_len = i2d_X509(signing_cert, NULL);
	if (tmp_der_len < 0) {
		res = GT_CRYPTO_FAILURE;
		goto cleanup;
	}

	tmp_der = GT_malloc(tmp_der_len);
	if (tmp_der == NULL) {
		res = GT_OUT_OF_MEMORY;
		goto cleanup;
	}

	i2dp = tmp_der;
	i2d_X509(signing_cert, &i2dp);

	*cert_der = tmp_der;
	tmp_der = NULL;
	*cert_der_length = tmp_der_len;

	res = GT_OK;

cleanup:
	GT_free(tmp_der);
	sk_X509_free(certs);

	return res;
}
Ejemplo n.º 26
0
/* find the issuer certificate without lookups */
NOEXPORT X509 *get_current_issuer(X509_STORE_CTX *callback_ctx) {
    STACK_OF(X509) *chain;
    int depth;

    chain=X509_STORE_CTX_get_chain(callback_ctx);
    depth=X509_STORE_CTX_get_error_depth(callback_ctx);
    if(depth<sk_X509_num(chain)-1) /* not the root CA cert */
        ++depth; /* index of the issuer cert */
    return sk_X509_value(chain, depth);
}
Ejemplo n.º 27
0
/**
  This function will return the leaf signer certificate in a chain.  This is
  required because certificate chains are not guaranteed to have the
  certificates in the order that they were issued.

  A typical certificate chain looks like this:


                 ----------------------------
                |            Root            |
                 ----------------------------
                               ^
                               |
                 ----------------------------
                |          Policy CA         | <-- Typical Trust Anchor.
                 ----------------------------
                               ^
                               |
                 ----------------------------
                |         Issuing CA         |
                 ----------------------------
                               ^
                               |
                 -----------------------------
                /  End-Entity (leaf) signer  / <-- Bottom certificate.
                -----------------------------  EKU: "1.3.6.1.4.1.311.76.9.21.1"
                                                    (Firmware Signing)


  @param[in]   CertChain            Certificate chain.

  @param[out]  SignerCert           Last certificate in the chain.  For PKCS7 signatures,
                                    this will be the end-entity (leaf) signer cert.

  @retval EFI_SUCCESS               The required EKUs were found in the signature.
  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
  @retval EFI_NOT_FOUND             The number of signers found was not 1.

**/
EFI_STATUS
GetSignerCertificate (
  IN CONST PKCS7 *CertChain,
  OUT X509       **SignerCert
  )
{
  EFI_STATUS      Status;
  STACK_OF(X509)  *Signers;
  INT32           NumberSigners;

  Status         = EFI_SUCCESS;
  Signers        = NULL;
  NumberSigners  = 0;

  if (CertChain == NULL || SignerCert == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Get the signers from the chain.
  //
  Signers = PKCS7_get0_signers ((PKCS7*) CertChain, NULL, PKCS7_BINARY);
  if (Signers == NULL) {
    //
    // Fail to get signers form PKCS7
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // There should only be one signer in the PKCS7 stack.
  //
  NumberSigners = sk_X509_num (Signers);
  if (NumberSigners != 1) {
    //
    // The number of singers should have been 1
    //
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  *SignerCert = sk_X509_value (Signers, 0);

Exit:
  //
  // Release Resources
  //
  if (Signers) {
    sk_X509_free (Signers);
  }

  return Status;
}
Ejemplo n.º 28
0
static int check_certificate_by_signer (X509 *peercert)
{
  X509_STORE_CTX *xsc;
  X509_STORE *ctx;
  int pass = 0, i;

  ctx = X509_STORE_new ();
  if (ctx == NULL) return 0;

  if (option (OPTSSLSYSTEMCERTS))
  {
    if (X509_STORE_set_default_paths (ctx))
      pass++;
    else
      dprint (2, (debugfile, "X509_STORE_set_default_paths failed\n"));
  }

  if (X509_STORE_load_locations (ctx, SslCertFile, NULL))
    pass++;
  else
    dprint (2, (debugfile, "X509_STORE_load_locations failed\n"));

  for (i = 0; i < sk_X509_num (SslSessionCerts); i++)
    pass += (X509_STORE_add_cert (ctx, sk_X509_value (SslSessionCerts, i)) != 0);

  if (pass == 0)
  {
    /* nothing to do */
    X509_STORE_free (ctx);
    return 0;
  }

  xsc = X509_STORE_CTX_new();
  if (xsc == NULL) return 0;
  X509_STORE_CTX_init (xsc, ctx, peercert, SslSessionCerts);

  pass = (X509_verify_cert (xsc) > 0);
#ifdef DEBUG
  if (! pass)
  {
    char buf[SHORT_STRING];
    int err;

    err = X509_STORE_CTX_get_error (xsc);
    snprintf (buf, sizeof (buf), "%s (%d)",
	X509_verify_cert_error_string(err), err);
    dprint (2, (debugfile, "X509_verify_cert: %s\n", buf));
    dprint (2, (debugfile, " [%s]\n", peercert->name));
  }
#endif
  X509_STORE_CTX_free (xsc);
  X509_STORE_free (ctx);

  return pass;
}
Ejemplo n.º 29
0
bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verifyCtx, const std::string &hostName)
{
    X509_STORE_CTX *storeContext = verifyCtx.native_handle();
    int currentDepth = X509_STORE_CTX_get_error_depth(storeContext);
    if (currentDepth != 0)
    {
        return true;
    }

    STACK_OF(X509) *certStack = X509_STORE_CTX_get_chain(storeContext);
    const int numCerts = sk_X509_num(certStack);
    if (numCerts < 0)
    {
        return false;
    }

    std::vector<std::string> certChain;
    certChain.reserve(numCerts);
    for (int i = 0; i < numCerts; ++i)
    {
        X509 *cert = sk_X509_value(certStack, i);

        // Encode into DER format into raw memory.
        int len = i2d_X509(cert, nullptr);
        if (len < 0)
        {
            return false;
        }

        std::string certData;
        certData.resize(len);
        unsigned char * buffer = reinterpret_cast<unsigned char *>(&certData[0]);
        len = i2d_X509(cert, &buffer);
        if (len < 0)
        {
            return false;
        }

        certChain.push_back(std::move(certData));
    }

    auto verify_result = verify_X509_cert_chain(certChain, hostName);

    // The Windows Crypto APIs don't do host name checks, use Boost's implementation.
#if defined(_WIN32)
    if (verify_result)
    {
        boost::asio::ssl::rfc2818_verification rfc2818(hostName);
        verify_result = rfc2818(verify_result, verifyCtx);
    }
#endif
    return verify_result;
}
Ejemplo n.º 30
0
// VerifyChain verifies the certificate chain in chain
// according to the verification options given as opts.
bool X509VerifierPrivate::VerifyChain(std::vector<X509Certificate> chain, const X509VerifierOptions &opts) {
	bool status = false;
	X509_STORE_CTX *ctx = X509_STORE_CTX_new();
	STACK_OF(X509) *untrusted = sk_X509_new_null();

	// Ensure that we have a chain to check on.
	if (chain.empty()) {
		goto out;
	}

	// If we've been passed a DNS name in opts,
	// we should check whether the leaf certificate
	// matches that before doing the more expensive
	// checks.
	if (!opts.dns_name.empty()) {
		if (!X509HostnameVerifier::VerifyHostname(chain.at(0), opts.dns_name)) {
			std::cerr << "X509VerifierPrivate - hostname verification failed" << std::endl;
			goto out;
		}
	}

	// Extract our chain into the format that OpenSSL
	// expects for verification.
	for (X509Certificate &cert : chain) {
		X509 *cur = cert.dptr_->AsOpenSSLX509();
		sk_X509_push(untrusted, cur);
	}

	// Set up the X509_STORE_CTX to verify according to opts.
	X509_STORE_CTX_init(ctx, store_, sk_X509_value(untrusted, 0), untrusted);
	// If a time is not specified in opts, use the current system time.
	if (opts.time == 0) {
		X509_STORE_CTX_set_time(ctx, 0, std::time(nullptr));
	} else {
		X509_STORE_CTX_set_time(ctx, 0, opts.time);
	}
	// If a dns_name is specified in opts, use the SSL server policy.
	if (!opts.dns_name.empty()) {
		X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SSL_SERVER);
		X509_STORE_CTX_set_trust(ctx, X509_TRUST_SSL_SERVER);
	}

	if (X509_verify_cert(ctx) == 1) {
		status = true;
	} else {
		std::cerr << "X509VerifierPrivate - verification error: " << X509_verify_cert_error_string(ctx->error) << std::endl;
	}

out:
	sk_X509_pop_free(untrusted, X509_free);
	X509_STORE_CTX_free(ctx);
	return status;
}