Ejemplo n.º 1
0
static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx)
	{
	LPSTR name;
	DWORD len, err;
	CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
	if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len))
		{
		err = GetLastError();
		if (err == ERROR_NO_MORE_ITEMS)
			return 2;
		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
		capi_adderror(err);
		return 0;
		}
	name = OPENSSL_malloc(len);
	if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len))
		{
		err = GetLastError();
		if (err == ERROR_NO_MORE_ITEMS)
			return 2;
		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
		capi_adderror(err);
		return 0;
		}
	*pname = name;
	CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype);

	return 1;
	}
Ejemplo n.º 2
0
static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
	{
	CAPI_KEY *key;
	key = OPENSSL_malloc(sizeof(CAPI_KEY));
	CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", 
						contname, provname, ptype);
	if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0))
		{
		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
		capi_addlasterror();
		goto err;
		}
	if (!CryptGetUserKey(key->hprov, keyspec, &key->key))
		{
		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
		capi_addlasterror();
		CryptReleaseContext(key->hprov, 0);
		goto err;
		}
	key->keyspec = keyspec;
	key->pcert = NULL;
	return key;

	err:
	OPENSSL_free(key);
	return NULL;
	}
Ejemplo n.º 3
0
int capi_rsa_priv_dec(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa, int padding)
	{
	int i;
	unsigned char *tmpbuf;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;
	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);

	CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");


	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
		return -1;
		}

	if(padding != RSA_PKCS1_PADDING)
		{
		char errstr[10];
		BIO_snprintf(errstr, 10, "%d", padding);
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
		ERR_add_error_data(2, "padding=", errstr);
		return -1;
		}

	/* Create temp reverse order version of input */
	if(!(tmpbuf = OPENSSL_malloc(flen)) ) 
		{
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
		return -1;
		}
	for(i = 0; i < flen; i++)
		tmpbuf[flen - i - 1] = from[i];
	
	/* Finally decrypt it */
	if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen))
		{
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
		capi_addlasterror();
		OPENSSL_free(tmpbuf);
		return -1;
		} 
	else memcpy(to, tmpbuf, flen);

	OPENSSL_free(tmpbuf);

	return flen;
	}
Ejemplo n.º 4
0
static void capi_ctx_free(CAPI_CTX *ctx)
	{
	CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
	if (!ctx)
		return;
	if (ctx->cspname)
		OPENSSL_free(ctx->cspname);
	if (ctx->debug_file)
		OPENSSL_free(ctx->debug_file);
	if (ctx->storename)
		OPENSSL_free(ctx->storename);
	if (ctx->ssl_client_store)
		OPENSSL_free(ctx->ssl_client_store);
	OPENSSL_free(ctx);
	}
Ejemplo n.º 5
0
HCERTSTORE capi_open_store(CAPI_CTX * ctx, char *storename)
{
    HCERTSTORE hstore;

    if (!storename)
        storename = ctx->storename;
    if (!storename)
        storename = "MY";
    CAPI_trace(ctx, "Opening certificate store %s\n", storename);

    hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0,
                           ctx->store_flags, storename);
    if (!hstore) {
        CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
        capi_addlasterror();
    }
    return hstore;
}
Ejemplo n.º 6
0
static int capi_list_providers(CAPI_CTX * ctx, BIO *out)
{
    DWORD idx, ptype;
    int ret;
    LPSTR provname = NULL;
    CAPI_trace(ctx, "capi_list_providers\n");
    BIO_printf(out, "Available CSPs:\n");
    for (idx = 0;; idx++) {
        ret = capi_get_provname(ctx, &provname, &ptype, idx);
        if (ret == 2)
            break;
        if (ret == 0)
            break;
        BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype);
        OPENSSL_free(provname);
    }
    return 1;
}
Ejemplo n.º 7
0
static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check)
	{
	CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
	if (check)
		{
		HCRYPTPROV hprov;
		if (!CryptAcquireContextA(&hprov, NULL, pname, type,
						CRYPT_VERIFYCONTEXT))
			{
			CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
			capi_addlasterror();
			return 0;
			}
		CryptReleaseContext(hprov, 0);
		}
	ctx->cspname = BUF_strdup(pname);
	ctx->csptype = type;
	return 1;
	}
Ejemplo n.º 8
0
int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
	{
	char *storename;
	int idx;
	int ret = 1;
	HCERTSTORE hstore;
	PCCERT_CONTEXT cert = NULL;

	storename = ctx->storename;
	if (!storename)
		storename = "MY";
	CAPI_trace(ctx, "Listing certs for store %s\n", storename);

	hstore = capi_open_store(ctx, storename);
	if (!hstore)
		return 0;
	if (id)
		{
		cert = capi_find_cert(ctx, id, hstore);
		if (!cert)
			{
			ret = 0;
			goto err;
			}
		capi_dump_cert(ctx, out, cert);
		CertFreeCertificateContext(cert);
		}
	else
		{
		for(idx = 0;;idx++)
			{
			LPWSTR fname = NULL;
			cert = CertEnumCertificatesInStore(hstore, cert);
			if (!cert)
				break;
			BIO_printf(out, "Certificate %d\n", idx);
			capi_dump_cert(ctx, out, cert);
			}
		}
	err:
	CertCloseStore(hstore, 0);
	return ret;
	}
Ejemplo n.º 9
0
char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
	{
	LPWSTR wfname;
	DWORD dlen;

	CAPI_trace(ctx, "capi_cert_get_fname\n");
	if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
		return NULL;
	wfname = OPENSSL_malloc(dlen);
	if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen))
		{
		char *fname = wide_to_asc(wfname);
		OPENSSL_free(wfname);
		return fname;
		}
	CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
	capi_addlasterror();

	OPENSSL_free(wfname);
	return NULL;
	}
Ejemplo n.º 10
0
static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
								DSA *dsa)
	{
	HCRYPTHASH hash;
	DWORD slen;
	DSA_SIG *ret = NULL;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;
	unsigned char csigbuf[40];

	ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);

	CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");

	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);

	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
		return NULL;
		}

	if (dlen != 20)
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
		return NULL;
		}

	/* Create the hash object */
	if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
		capi_addlasterror();
		return NULL;
		}

	/* Set the hash value to the value passed */
	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
		capi_addlasterror();
		goto err;
		}


	/* Finally sign it */
	slen = sizeof(csigbuf);
	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
		capi_addlasterror();
		goto err;
		}
	else
		{
		ret = DSA_SIG_new();
		if (!ret)
			goto err;
		ret->r = BN_new();
		ret->s = BN_new();
		if (!ret->r || !ret->s)
			goto err;
		if (!lend_tobn(ret->r, csigbuf, 20)
			|| !lend_tobn(ret->s, csigbuf + 20, 20))
			{
			DSA_SIG_free(ret);
			ret = NULL;
			goto err;
			}
		}

	/* Now cleanup */

err:
	OPENSSL_cleanse(csigbuf, 40);
	CryptDestroyHash(hash);
	return ret;
	}
Ejemplo n.º 11
0
int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
             unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
	{
	ALG_ID alg;
	HCRYPTHASH hash;
	DWORD slen;
	unsigned int i;
	int ret = -1;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;

	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);

	CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");

	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
		return -1;
		}
/* Convert the signature type to a CryptoAPI algorithm ID */
	switch(dtype)
		{
	case NID_sha1:
		alg = CALG_SHA1;
		break;

	case NID_md5:
		alg = CALG_MD5;
		break;

	case NID_md5_sha1:
		alg = CALG_SSL3_SHAMD5;
		break;
	default:
		{
		char algstr[10];
		BIO_snprintf(algstr, 10, "%lx", dtype);
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
		ERR_add_error_data(2, "NID=0x", algstr);
		return -1;
		}
	}



/* Create the hash object */
	if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
		capi_addlasterror();
		return -1;
		}
/* Set the hash value to the value passed */

	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
		capi_addlasterror();
		goto err;
		}


/* Finally sign it */
	slen = RSA_size(rsa);
	if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
		capi_addlasterror();
		goto err;
		}
	else
		{
		ret = 1;
		/* Inplace byte reversal of signature */
		for(i = 0; i < slen / 2; i++)
			{
			unsigned char c;
			c = sigret[i];
			sigret[i] = sigret[slen - i - 1];
			sigret[slen - i - 1] = c;
			}
		*siglen = slen;
		}

	/* Now cleanup */

err:
	CryptDestroyHash(hash);

	return ret;
	}
Ejemplo n.º 12
0
static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
	{
	int ret = 1;
	CAPI_CTX *ctx;
	BIO *out;
	if (capi_idx == -1)
		{
		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
		return 0;
		}
	ctx = ENGINE_get_ex_data(e, capi_idx);
	out = BIO_new_fp(stdout, BIO_NOCLOSE);
	switch (cmd)
		{
		case CAPI_CMD_LIST_CSPS:
		ret = capi_list_providers(ctx, out);
		break;

		case CAPI_CMD_LIST_CERTS:
		ret = capi_list_certs(ctx, out, NULL);
		break;

		case CAPI_CMD_LOOKUP_CERT:
		ret = capi_list_certs(ctx, out, p);
		break;

		case CAPI_CMD_LIST_CONTAINERS:
		ret = capi_list_containers(ctx, out);
		break;

		case CAPI_CMD_STORE_NAME:
		if (ctx->storename)
			OPENSSL_free(ctx->storename);
		ctx->storename = BUF_strdup(p);
		CAPI_trace(ctx, "Setting store name to %s\n", p);
		break;

		case CAPI_CMD_STORE_FLAGS:
		if (i & 1)
			{
			ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
			ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
			}
		else
			{
			ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
			ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
			}
		CAPI_trace(ctx, "Setting flags to %d\n", i);
		break;

		case CAPI_CMD_DEBUG_LEVEL:
		ctx->debug_level = (int)i;
		CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
		break;

		case CAPI_CMD_DEBUG_FILE:
		ctx->debug_file = BUF_strdup(p);
		CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
		break;

		case CAPI_CMD_KEYTYPE:
		ctx->keytype = i;
		CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
		break;

		case CAPI_CMD_SET_CSP_IDX:
		ret = capi_ctx_set_provname_idx(ctx, i);
		break;

		case CAPI_CMD_LIST_OPTIONS:
		ctx->dump_flags = i;
		break;

		case CAPI_CMD_LOOKUP_METHOD:
		if (i < 1 || i > 3)
			{
			CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
			return 0;
			}
		ctx->lookup_method = i;
		break;

		case CAPI_CMD_SET_CSP_NAME:
		ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
		break;

		case CAPI_CMD_SET_CSP_TYPE:
		ctx->csptype = i;
		break;

		default:
		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
		ret = 0;
	}

	BIO_free(out);
	return ret;

	}
Ejemplo n.º 13
0
static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
	{
	int ret = 1;
	HCRYPTPROV hprov;
	DWORD err, idx, flags, buflen = 0, clen;
	LPSTR cname;
	CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
	if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
		{
		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
		capi_addlasterror();
		return 0;
		}
	if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST))
		{
		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
		capi_addlasterror();
		return 0;
		}
	CAPI_trace(ctx, "Got max container len %d\n", buflen);
	if (buflen == 0)
		buflen = 1024;
	cname = OPENSSL_malloc(buflen);
	if (!cname)
		{
		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	for (idx = 0;;idx++)
		{
		clen = buflen;
		cname[0] = 0;

		if (idx == 0)
			flags = CRYPT_FIRST;
		else
			flags = 0;
		if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags))
			{
			err = GetLastError();
			if (err == ERROR_NO_MORE_ITEMS)
				goto done;
			CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
			capi_adderror(err);
			goto err;
			}
		CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags);
		if (!cname[0] && (clen == buflen))
			{
			CAPI_trace(ctx, "Enumerate bug: using workaround\n");
			goto done;
			}
		BIO_printf(out, "%d. %s\n", idx, cname);
		}
	err:

	ret = 0;

	done:
	if (cname)
		OPENSSL_free(cname);
	CryptReleaseContext(hprov, 0);

	return ret;
	}