Beispiel #1
0
static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
	 CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
{
	PKCS11_TOKEN_private *tpriv;
	PKCS11_CERT_private *kpriv;
	PKCS11_CERT *cert, *tmp;
	char label[256], data[2048];
	unsigned char id[256];
	CK_CERTIFICATE_TYPE cert_type;
	size_t size;

	size = sizeof(cert_type);
	if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, &cert_type, &size))
		return -1;

	/* Ignore any certs we don't understand */
	if (cert_type != CKC_X_509)
		return 0;

	tpriv = PRIVTOKEN(token);
	tmp = (PKCS11_CERT *) OPENSSL_realloc(tpriv->certs,
				(tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
	if (!tmp) {
		free(tpriv->certs);
		tpriv->certs = NULL;
		return -1;
	}
	tpriv->certs = tmp;

	cert = tpriv->certs + tpriv->ncerts++;
	memset(cert, 0, sizeof(*cert));
	cert->_private = kpriv = PKCS11_NEW(PKCS11_CERT_private);
	kpriv->object = obj;
	kpriv->parent = token;

	if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label)))
		cert->label = BUF_strdup(label);
	size = sizeof(data);
	if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) {
		const unsigned char *p = (unsigned char *) data;

		cert->x509 = d2i_X509(NULL, &p, size);
	}
	cert->id_len = sizeof(id);
	if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &cert->id_len)) {
		cert->id = (unsigned char *) malloc(cert->id_len);
		memcpy(cert->id, id, cert->id_len);
	}

	/* Initialize internal information */
	kpriv->id_len = sizeof(kpriv->id);
	if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len))
		kpriv->id_len = 0;

	if (ret)
		*ret = cert;

	return 0;
}
Beispiel #2
0
int
pkcs11_getattr_s(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
		 unsigned int type, void *value, size_t size)
{
	memset(value, 0, size);
	return pkcs11_getattr_var(token, object, type, value, &size);
}
Beispiel #3
0
int
pkcs11_getattr_bn(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
		  unsigned int type, BIGNUM ** bn)
{
	CK_BYTE binary[4196 / 8];
	size_t size = sizeof(binary);

	if (pkcs11_getattr_var(token, object, type, binary, &size))
		return -1;
	if (size == -1) {
		PKCS11err(PKCS11_F_PKCS11_GETATTR,
			  pkcs11_map_err(CKR_ATTRIBUTE_TYPE_INVALID));
		return -1;
	}
	*bn = BN_bin2bn(binary, size, *bn);
	return *bn ? 0 : -1;
}
Beispiel #4
0
static int pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
		CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
		CK_OBJECT_CLASS type, PKCS11_KEY ** ret)
{
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
	PKCS11_KEY_private *kpriv;
	PKCS11_KEY *key, *tmp;
	CK_KEY_TYPE key_type;
	PKCS11_KEY_ops *ops;
	size_t size;

	(void)ctx;
	(void)session;

	size = sizeof(key_type);
	if (pkcs11_getattr_var(token, obj, CKA_KEY_TYPE, (CK_BYTE *)&key_type, &size))
		return -1;

	switch (key_type) {
	case CKK_RSA:
		ops = &pkcs11_rsa_ops;
		break;
	case CKK_EC:
		ops = pkcs11_ec_ops;
		if (ops == NULL)
			return 0; /* not supported */
		break;
	default:
		/* Ignore any keys we don't understand */
		return 0;
	}

	tmp = OPENSSL_realloc(keys->keys, (keys->num + 1) * sizeof(PKCS11_KEY));
	if (tmp == NULL) {
		OPENSSL_free(keys->keys);
		keys->keys = NULL;
		return -1;
	}
	keys->keys = tmp;

	key = keys->keys + keys->num++;
	memset(key, 0, sizeof(PKCS11_KEY));
	kpriv = OPENSSL_malloc(sizeof(PKCS11_KEY_private));
	if (kpriv)
		memset(kpriv, 0, sizeof(PKCS11_KEY_private));
	key->_private = kpriv;
	kpriv->object = obj;
	kpriv->parent = token;

	pkcs11_getattr_alloc(token, obj, CKA_LABEL, (CK_BYTE **)&key->label, NULL);
	key->id_len = 0;
	pkcs11_getattr_alloc(token, obj, CKA_ID, &key->id, &key->id_len);
	key->isPrivate = (type == CKO_PRIVATE_KEY);

	/* Initialize internal information */
	kpriv->id_len = sizeof(kpriv->id);
	if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len))
		kpriv->id_len = 0;
	kpriv->ops = ops;
	kpriv->forkid = _P11_get_forkid();

	if (ret)
		*ret = key;
	return 0;
}
Beispiel #5
0
static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
		CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
{
	PKCS11_TOKEN_private *tpriv;
	PKCS11_CERT_private *cpriv;
	PKCS11_CERT *cert, *tmp;
	unsigned char *data;
	CK_CERTIFICATE_TYPE cert_type;
	size_t size;

	(void)ctx;
	(void)session;

	size = sizeof(cert_type);
	if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, (CK_BYTE *)&cert_type, &size))
		return -1;

	/* Ignore any certs we don't understand */
	if (cert_type != CKC_X_509)
		return 0;

	tpriv = PRIVTOKEN(token);
	tmp = OPENSSL_realloc(tpriv->certs,
		(tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
	if (tmp == NULL) {
		OPENSSL_free(tpriv->certs);
		tpriv->certs = NULL;
		return -1;
	}
	tpriv->certs = tmp;

	cert = tpriv->certs + tpriv->ncerts++;
	memset(cert, 0, sizeof(*cert));
	cpriv = OPENSSL_malloc(sizeof(PKCS11_CERT_private));
	if (cpriv == NULL)
		return -1;
	memset(cpriv, 0, sizeof(PKCS11_CERT_private));
	cert->_private = cpriv;
	cpriv->object = obj;
	cpriv->parent = token;

	pkcs11_getattr_alloc(token, obj, CKA_LABEL, (CK_BYTE **)&cert->label, NULL);
	size = 0;
	if (!pkcs11_getattr_alloc(token, obj, CKA_VALUE, &data, &size)) {
		const unsigned char *p = data;

		cert->x509 = d2i_X509(NULL, &p, (long)size);
		OPENSSL_free(data);
	}
	cert->id_len = 0;
	pkcs11_getattr_alloc(token, obj, CKA_ID, &cert->id, &cert->id_len);

	/* Initialize internal information */
	cpriv->id_len = sizeof(cpriv->id);
	if (pkcs11_getattr_var(token, obj, CKA_ID, cpriv->id, &cpriv->id_len))
		cpriv->id_len = 0;

	if (ret)
		*ret = cert;
	return 0;
}
Beispiel #6
0
/* initial code will only support what is needed for pkcs11_ec_ckey
 * i.e. CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE
 * and CK_EC_KDF_TYPE  supported by token
 * The secret key object is deleted
 *
 * In future CKM_ECMQV_DERIVE with CK_ECMQV_DERIVE_PARAMS
 * could also be supported, and the secret key object could be returned. 
 */
int pkcs11_ecdh_derive_internal(unsigned char **out, size_t *outlen,
		const unsigned long ecdh_mechanism,
		const void * ec_params,
		void *outnewkey,
		PKCS11_KEY * key)
{
	int rv;
	int ret = -1;
	unsigned char * buf = NULL;
	size_t buflen;
	PKCS11_KEY_private *priv;
	PKCS11_SLOT *slot;
	PKCS11_CTX *ctx;
	PKCS11_TOKEN *token;
	CK_SESSION_HANDLE session;
	CK_MECHANISM mechanism;

	CK_BBOOL true = TRUE;
	CK_BBOOL false = FALSE;
	CK_OBJECT_HANDLE newkey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS newkey_class= CKO_SECRET_KEY;
	CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET;
	CK_OBJECT_HANDLE * tmpnewkey = (CK_OBJECT_HANDLE *)outnewkey;
	CK_ATTRIBUTE newkey_template[] = {
		{CKA_TOKEN, &false, sizeof(false)}, /* session only object */
		{CKA_CLASS, &newkey_class, sizeof(newkey_class)},
		{CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)},
		{CKA_ENCRYPT, &true, sizeof(true)},
		{CKA_DECRYPT, &true, sizeof(true)}
	};

	ctx = KEY2CTX(key);
	priv = PRIVKEY(key);
	token = KEY2TOKEN(key);
	slot = KEY2SLOT(key);

	CHECK_KEY_FORK(key);

	session = PRIVSLOT(slot)->session;

	memset(&mechanism, 0, sizeof(mechanism));
	mechanism.mechanism  = ecdh_mechanism;
	mechanism.pParameter =  (void*)ec_params;
	switch (ecdh_mechanism) {
		case CKM_ECDH1_DERIVE:
		case CKM_ECDH1_COFACTOR_DERIVE:
			mechanism.ulParameterLen  = sizeof(CK_ECDH1_DERIVE_PARAMS);
			break;
//		case CK_ECMQV_DERIVE_PARAMS:
//			mechanism.ulParameterLen  = sizeof(CK_ECMQV_DERIVE_PARAMS);
//			break;
		default:
		    PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY, PKCS11_NOT_SUPPORTED);
		    goto err;
	}

	CRYPTO_w_lock(PRIVSLOT(slot)->lockid);
	rv = CRYPTOKI_call(ctx, C_DeriveKey(session, &mechanism, priv->object, newkey_template, 5, &newkey));
	if (rv) {
	    PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY, pkcs11_map_err(rv));
	    goto err;
	}

	/* Return the value of the secret key and/or the object handle of the secret key */
	
	/* pkcs11_ec_ckey only asks for the value */

	if (out && outlen) {
		/* get size of secret key value */
		if (!pkcs11_getattr_var(token, newkey, CKA_VALUE, NULL, &buflen)
			&& buflen > 0) {
			buf = OPENSSL_malloc(buflen);
			if (buf == NULL) {
				PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY,
					pkcs11_map_err(CKR_HOST_MEMORY));
				goto err;
			}
		} else {
			PKCS11err(PKCS11_F_PKCS11_EC_KEY_COMPUTE_KEY,
				pkcs11_map_err(CKR_ATTRIBUTE_VALUE_INVALID));
			goto err;
		}

		pkcs11_getattr_var(token, newkey, CKA_VALUE, buf, &buflen);
		*out = buf;
		*outlen = buflen;
		buf = NULL;
	}

	/* not used by pkcs11_ec_ckey for future use */
	if (tmpnewkey) {
	    *tmpnewkey = newkey;
	    newkey = CK_INVALID_HANDLE;
	}

	ret = 1;
err:
	if (buf)
	    OPENSSL_free(buf);
	if (newkey != CK_INVALID_HANDLE && session != CK_INVALID_HANDLE)
		CRYPTOKI_call(ctx, C_DestroyObject(session, newkey));
	
	return ret;
}