Пример #1
0
void
pkcs11h_openssl_freeSession (
	IN const pkcs11h_openssl_session_t openssl_session
) {
	CK_RV rv;

	_PKCS11H_ASSERT (openssl_session!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d",
		(void *)openssl_session,
		openssl_session->reference_count
	);

#if defined(ENABLE_PKCS11H_THREADING)
	if ((rv = _pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock)) != CKR_OK) {
		_PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot lock mutex %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}
#endif
	openssl_session->reference_count--;
#if defined(ENABLE_PKCS11H_THREADING)
	_pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock);
#endif

	_PKCS11H_ASSERT (openssl_session->reference_count>=0);

	if (openssl_session->reference_count == 0) {
#if defined(ENABLE_PKCS11H_THREADING)
		_pkcs11h_threading_mutexFree(&openssl_session->reference_count_lock);
#endif

		if (openssl_session->cleanup_hook != NULL) {
			openssl_session->cleanup_hook (openssl_session->certificate);
		}

		if (openssl_session->x509 != NULL) {
			X509_free (openssl_session->x509);
			openssl_session->x509 = NULL;
		}
		if (openssl_session->certificate != NULL) {
			pkcs11h_certificate_freeCertificate (openssl_session->certificate);
			openssl_session->certificate = NULL;
		}

		_pkcs11h_mem_free ((void *)&openssl_session);
	}

cleanup:

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_freeSession - return"
	);
}
Пример #2
0
/**
   Return certificate contents. Line contains the percent-plus escaped
   certificate ID.
*/
gpg_error_t cmd_readcert (assuan_context_t ctx, char *line)
{
	gpg_err_code_t error = GPG_ERR_GENERAL;
	pkcs11h_certificate_id_t cert_id = NULL;
	pkcs11h_certificate_t cert = NULL;
	unsigned char *blob = NULL;
	size_t blob_size;

	if (
		(error = _get_certificate_by_name (
			ctx,
			line,
			0,
			&cert_id,
			NULL
		)) != GPG_ERR_NO_ERROR ||
		(error = get_cert_blob (ctx, cert_id, &blob, &blob_size)) != GPG_ERR_NO_ERROR ||
		(error = assuan_send_data (ctx, blob, blob_size)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	error = GPG_ERR_NO_ERROR;

cleanup:

	if (cert != NULL) {
		pkcs11h_certificate_freeCertificate (cert);
		cert = NULL;
	}

	if (cert_id != NULL) {
		pkcs11h_certificate_freeCertificateId (cert_id);
		cert_id = NULL;
	}

	if (blob != NULL) {
		free (blob);
		blob = NULL;
	}

	return gpg_error (error);
}
Пример #3
0
void pkcs11_priv_key_free( pkcs11_context *priv_key )
{
    if( NULL != priv_key )
        pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
}
Пример #4
0
void
show_pkcs11_ids(
    const char *const provider,
    bool cert_private
    ) {
    struct gc_arena gc = gc_new();
    pkcs11h_certificate_id_list_t user_certificates = NULL;
    pkcs11h_certificate_id_list_t current = NULL;
    CK_RV rv = CKR_FUNCTION_FAILED;

    if ((rv = pkcs11h_initialize()) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));

    if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (rv = pkcs11h_addProvider(
             provider,
             provider,
             TRUE,
             0,
             FALSE,
             0,
             cert_private ? TRUE : FALSE
             )) != CKR_OK
        )
    {
        msg(M_FATAL, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (rv = pkcs11h_certificate_enumCertificateIds(
             PKCS11H_ENUM_METHOD_CACHE_EXIST,
             NULL,
             PKCS11H_PROMPT_MASK_ALLOW_ALL,
             NULL,
             &user_certificates
             )) != CKR_OK
        )
    {
        msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    msg(
        M_INFO|M_NOPREFIX|M_NOLF,
        (
            "\n"
            "The following objects are available for use.\n"
            "Each object shown below may be used as parameter to\n"
            "--pkcs11-id option please remember to use single quote mark.\n"
        )
        );
    for (current = user_certificates; current != NULL; current = current->next) {
        pkcs11h_certificate_t certificate = NULL;
        char *dn = NULL;
        char serial[1024] = {0};
        char *ser = NULL;
        size_t ser_len = 0;

        if (
            (rv = pkcs11h_certificate_serializeCertificateId(
                 NULL,
                 &ser_len,
                 current->certificate_id
                 )) != CKR_OK
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            rv == CKR_OK
            && (ser = (char *)malloc(ser_len)) == NULL
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot allocate memory");
            goto cleanup1;
        }

        if (
            (rv = pkcs11h_certificate_serializeCertificateId(
                 ser,
                 &ser_len,
                 current->certificate_id
                 )) != CKR_OK
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            (rv = pkcs11h_certificate_create(
                 current->certificate_id,
                 NULL,
                 PKCS11H_PROMPT_MASK_ALLOW_ALL,
                 PKCS11H_PIN_CACHE_INFINITE,
                 &certificate
                 ))
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            (dn = pkcs11_certificate_dn(
                 certificate,
                 &gc
                 )) == NULL
            )
        {
            goto cleanup1;
        }

        if (
            (pkcs11_certificate_serial(
                 certificate,
                 serial,
                 sizeof(serial)
                 ))
            )
        {
            goto cleanup1;
        }

        msg(
            M_INFO|M_NOPREFIX|M_NOLF,
            (
                "\n"
                "Certificate\n"
                "       DN:             %s\n"
                "       Serial:         %s\n"
                "       Serialized id:  %s\n"
            ),
            dn,
            serial,
            ser
            );

cleanup1:

        if (certificate != NULL)
        {
            pkcs11h_certificate_freeCertificate(certificate);
            certificate = NULL;
        }

        if (ser != NULL)
        {
            free(ser);
            ser = NULL;
        }
    }

cleanup:
    if (user_certificates != NULL)
    {
        pkcs11h_certificate_freeCertificateIdList(user_certificates);
        user_certificates = NULL;
    }

    pkcs11h_terminate();
    gc_free(&gc);
}
Пример #5
0
int
tls_ctx_use_pkcs11(
    struct tls_root_ctx *const ssl_ctx,
    bool pkcs11_id_management,
    const char *const pkcs11_id
    ) {
    pkcs11h_certificate_id_t certificate_id = NULL;
    pkcs11h_certificate_t certificate = NULL;
    CK_RV rv = CKR_OK;

    bool ok = false;

    ASSERT(ssl_ctx!=NULL);
    ASSERT(pkcs11_id_management || pkcs11_id!=NULL);

    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
        (void *)ssl_ctx,
        pkcs11_id_management ? 1 : 0,
        pkcs11_id
        );

    if (pkcs11_id_management)
    {
        struct user_pass id_resp;

        CLEAR(id_resp);

        id_resp.defined = false;
        id_resp.nocache = true;
        openvpn_snprintf(
            id_resp.username,
            sizeof(id_resp.username),
            "Please specify PKCS#11 id to use"
            );

        if (
            !get_user_pass(
                &id_resp,
                NULL,
                "pkcs11-id-request",
                GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_STR|GET_USER_PASS_NOFATAL
                )
            )
        {
            goto cleanup;
        }

        if (
            (rv = pkcs11h_certificate_deserializeCertificateId(
                 &certificate_id,
                 id_resp.password
                 )) != CKR_OK
            )
        {
            msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup;
        }
    }
    else
    {
        if (
            (rv = pkcs11h_certificate_deserializeCertificateId(
                 &certificate_id,
                 pkcs11_id
                 )) != CKR_OK
            )
        {
            msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup;
        }
    }

    if (
        (rv = pkcs11h_certificate_create(
             certificate_id,
             NULL,
             PKCS11H_PROMPT_MASK_ALLOW_ALL,
             PKCS11H_PIN_CACHE_INFINITE,
             &certificate
             )) != CKR_OK
        )
    {
        msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (pkcs11_init_tls_session(
             certificate,
             ssl_ctx
             ))
        )
    {
        /* Handled by SSL context free */
        certificate = NULL;
        goto cleanup;
    }

    /* Handled by SSL context free */
    certificate = NULL;
    ok = true;

cleanup:
    if (certificate != NULL)
    {
        pkcs11h_certificate_freeCertificate(certificate);
        certificate = NULL;
    }

    if (certificate_id != NULL)
    {
        pkcs11h_certificate_freeCertificateId(certificate_id);
        certificate_id = NULL;
    }

    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld",
        ok ? 1 : 0,
        rv
        );

    return ok ? 1 : 0;
}
Пример #6
0
/** Sign data (set by SETDATA) with certificate id in line. */
gpg_error_t cmd_pksign (assuan_context_t ctx, char *line)
{
	static const unsigned char rmd160_prefix[] = /* (1.3.36.3.2.1) */
		{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
		0x02, 0x01, 0x05, 0x00, 0x04, 0x14  };
	static const unsigned char md5_prefix[] =   /* (1.2.840.113549.2.5) */
		{ 0x30, 0x2c, 0x30, 0x09, 0x06, 0x08, 0x2a, 0x86, 0x48,
		0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10  };
	static const unsigned char sha1_prefix[] =   /* (1.3.14.3.2.26) */
		{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
		0x02, 0x1a, 0x05, 0x00, 0x04, 0x14  };
	static const unsigned char sha224_prefix[] = /* (2.16.840.1.101.3.4.2.4) */
		{ 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
		0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
		0x1C  };
	static const unsigned char sha256_prefix[] = /* (2.16.840.1.101.3.4.2.1) */
		{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
		0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
		0x00, 0x04, 0x20  };
	static const unsigned char sha384_prefix[] = /* (2.16.840.1.101.3.4.2.2) */
		{ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
		0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
		0x00, 0x04, 0x30  };
	static const unsigned char sha512_prefix[] = /* (2.16.840.1.101.3.4.2.3) */
		{ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
		0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
		0x00, 0x04, 0x40  };

	gpg_err_code_t error = GPG_ERR_GENERAL;
	pkcs11h_certificate_id_t cert_id = NULL;
	pkcs11h_certificate_t cert = NULL;
	cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx);
	cmd_data_t *_data = data;
	int need_free__data = 0;
	int session_locked = 0;
	unsigned char *sig = NULL;
	size_t sig_len;
	char hash[100] = "";
	enum {
		INJECT_NONE,
		INJECT_RMD160,
		INJECT_MD5,
		INJECT_SHA1,
		INJECT_SHA224,
		INJECT_SHA256,
		INJECT_SHA384,
		INJECT_SHA512
	} inject = INJECT_NONE;

	if (data->data == NULL) {
		error = GPG_ERR_INV_DATA;
		goto cleanup;
	}

	while (*line != '\x0' && (isspace (*line) || *line == '-')) {
		if (*line == '-') {
			static const char *hashprm = "--hash=";
			char *p = line;

			while (*line != '\x0' && !isspace (*line)) {
				line++;
			}
			line++;

			if (!strncmp (p, hashprm, strlen (hashprm))) {
				p += strlen (hashprm);
				*(line-1) = '\0';
				snprintf (hash, sizeof(hash), "%s", p);
			}
		}
		else {
			line++;
		}
	}

	if (*line == '\x0') {
		error = GPG_ERR_INV_DATA;
		goto cleanup;
	}
	/*
	 * sender prefixed data with algorithm OID
	 */
	if (strcmp(hash, "")) {
		if (!strcmp(hash, "rmd160") && data->size == (0x14 + sizeof(rmd160_prefix)) &&
			!memcmp (data->data, rmd160_prefix, sizeof (rmd160_prefix))) {
			inject = INJECT_NONE;
		}
		else if (!strcmp(hash, "rmd160") && data->size == 0x14) {
			inject = INJECT_RMD160;
		}
		else if (!strcmp(hash, "md5") && data->size == (0x10 + sizeof(md5_prefix)) &&
			!memcmp (data->data, md5_prefix, sizeof (md5_prefix))) {
			inject = INJECT_NONE;
		}
		else if (!strcmp(hash, "md5") && data->size == 0x10) {
			inject = INJECT_MD5;
		}
		else if (!strcmp(hash, "sha1") && data->size == (0x14 + sizeof(sha1_prefix)) &&
			!memcmp (data->data, sha1_prefix, sizeof (sha1_prefix))) {
			inject = INJECT_NONE;
		}
		else if (!strcmp(hash, "sha1") && data->size == 0x14) {
			inject = INJECT_SHA1;
		}
		else if (!strcmp(hash, "sha224") && data->size == (0x1c + sizeof(sha224_prefix)) &&
			!memcmp (data->data, sha224_prefix, sizeof (sha224_prefix))) {
			inject = INJECT_NONE;
		}
		else if (!strcmp(hash, "sha224") && data->size == 0x1c) {
			inject = INJECT_SHA224;
		}
		else if (!strcmp(hash, "sha256") && data->size == (0x20 + sizeof(sha256_prefix)) &&
			!memcmp (data->data, sha256_prefix, sizeof (sha256_prefix))) {
			inject = INJECT_NONE;
		}
		else if (!strcmp(hash, "sha256") && data->size == 0x20) {
			inject = INJECT_SHA256;
		}
		else if (!strcmp(hash, "sha384") && data->size == (0x30 + sizeof(sha384_prefix)) &&
			!memcmp (data->data, sha384_prefix, sizeof (sha384_prefix))) {
			inject = INJECT_NONE;
		}
		else if (!strcmp(hash, "sha384") && data->size == 0x30) {
			inject = INJECT_SHA384;
		}
		else if (!strcmp(hash, "sha512") && data->size == (0x40 + sizeof(sha512_prefix)) &&
			!memcmp (data->data, sha512_prefix, sizeof (sha512_prefix))) {
			inject = INJECT_NONE;
		}
		else if (!strcmp(hash, "sha512") && data->size == 0x40) {
			inject = INJECT_SHA512;
		}
		else {
			common_log (LOG_DEBUG, "unsupported hash algo (hash=%s,size=%d)", hash, data->size);
			error = GPG_ERR_UNSUPPORTED_ALGORITHM;
			goto cleanup;
		}
	}
	else {
		if (
			data->size == 0x10 + sizeof (md5_prefix) ||
			data->size == 0x14 + sizeof (sha1_prefix) ||
			data->size == 0x14 + sizeof (rmd160_prefix)
		) {
			if (
				memcmp (data->data, md5_prefix, sizeof (md5_prefix)) &&
				memcmp (data->data, sha1_prefix, sizeof (sha1_prefix)) &&
				memcmp (data->data, rmd160_prefix, sizeof (rmd160_prefix))
			) {
				error = GPG_ERR_UNSUPPORTED_ALGORITHM;
				goto cleanup;
			}
		}
		else {
			/*
			 * unknown hash algorithm;
			 * gnupg's scdaemon forces to SHA1
			 */
			inject = INJECT_SHA1;
		}
	}

	if (inject != INJECT_NONE) {
		const unsigned char *oid;
		size_t oid_size;
		switch (inject) {
			case INJECT_RMD160:
				oid = rmd160_prefix;
				oid_size = sizeof (rmd160_prefix);
			break;
			case INJECT_MD5:
				oid = md5_prefix;
				oid_size = sizeof (md5_prefix);
			break;
			case INJECT_SHA1:
				oid = sha1_prefix;
				oid_size = sizeof (sha1_prefix);
			break;
			case INJECT_SHA224:
				oid = sha224_prefix;
				oid_size = sizeof (sha224_prefix);
			break;
			case INJECT_SHA256:
				oid = sha256_prefix;
				oid_size = sizeof(sha256_prefix);
			break;
			case INJECT_SHA384:
				oid = sha384_prefix;
				oid_size = sizeof(sha384_prefix);
			break;
			case INJECT_SHA512:
				oid = sha512_prefix;
				oid_size = sizeof(sha512_prefix);
			break;
			default:
				error = GPG_ERR_INV_DATA;
				goto cleanup;
		}

		need_free__data = 1;

		if ((_data = (cmd_data_t *)malloc (sizeof (cmd_data_t))) == NULL) {
			error = GPG_ERR_ENOMEM;
			goto cleanup;
		}

		if ((_data->data = (unsigned char *)malloc (data->size + oid_size)) == NULL) {
			error = GPG_ERR_ENOMEM;
			goto cleanup;
		}

		_data->size = 0;
		memmove (_data->data+_data->size, oid, oid_size);
		_data->size += oid_size;
		memmove (_data->data+_data->size, data->data, data->size);
		_data->size += data->size;
	}

	if (
		(error = _get_certificate_by_name (
			ctx,
			line,
			OPENPGP_SIGN,
			&cert_id,
			NULL
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_create (
				cert_id,
				ctx,
				PKCS11H_PROMPT_MASK_ALLOW_ALL,
				PKCS11H_PIN_CACHE_INFINITE,
				&cert
			)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_lockSession (cert)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}
	session_locked = 1;

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_signAny (
				cert,
				CKM_RSA_PKCS,
				_data->data,
				_data->size,
				NULL,
				&sig_len
			)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	if ((sig = (unsigned char *)malloc (sig_len)) == NULL) {
		error = GPG_ERR_ENOMEM;
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_signAny (
				cert,
				CKM_RSA_PKCS,
				_data->data,
				_data->size,
				sig,
				&sig_len
			)
		)) != GPG_ERR_NO_ERROR ||
		(error = assuan_send_data(ctx, sig, sig_len)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	error = GPG_ERR_NO_ERROR;

cleanup:

	if (session_locked) {
		pkcs11h_certificate_releaseSession (cert);
		session_locked = 0;
	}

	if (cert != NULL) {
		pkcs11h_certificate_freeCertificate (cert);
		cert = NULL;
	}

	if (cert_id != NULL) {
		pkcs11h_certificate_freeCertificateId (cert_id);
		cert_id = NULL;
	}

	if (sig != NULL) {
		free (sig);
		sig = NULL;
	}

	if (need_free__data) {
		free (_data->data);
		_data->data = NULL;
		free (_data);
		_data = NULL;
	}

	return gpg_error (error);
}
Пример #7
0
static
gpg_err_code_t
get_cert_blob (
	assuan_context_t ctx,
	pkcs11h_certificate_id_t cert_id,
	unsigned char **p_blob,
	size_t *p_blob_size
) {
	gpg_err_code_t error = GPG_ERR_GENERAL;
	pkcs11h_certificate_t cert = NULL;
	unsigned char *blob = NULL;
	size_t blob_size;

	*p_blob = NULL;
	*p_blob_size = 0;

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_create (
				cert_id,
				ctx,
				PKCS11H_PROMPT_MASK_ALLOW_ALL,
				PKCS11H_PIN_CACHE_INFINITE,
				&cert
			)
		)) != GPG_ERR_NO_ERROR ||
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_getCertificateBlob (
				cert,
				NULL,
				&blob_size
			)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	if ((blob = (unsigned char *)malloc (blob_size)) == NULL) {
		error = GPG_ERR_ENOMEM;
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_getCertificateBlob (
				cert,
				blob,
				&blob_size
			)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	*p_blob = blob;
	*p_blob_size = blob_size;
	blob = NULL;

	error = GPG_ERR_NO_ERROR;

cleanup:

	if (cert != NULL) {
		pkcs11h_certificate_freeCertificate (cert);
		cert = NULL;
	}

	if (blob != NULL) {
		free (blob);
		blob = NULL;
	}

	return error;
}
Пример #8
0
/** Decrypt data (set by SETDATA) with certificate id in line. */
gpg_error_t cmd_pkdecrypt (assuan_context_t ctx, char *line)
{
	gpg_err_code_t error = GPG_ERR_GENERAL;
	pkcs11h_certificate_id_t cert_id = NULL;
	pkcs11h_certificate_t cert = NULL;
	unsigned char *ptext = NULL;
	size_t ptext_len;
	int session_locked = 0;
	cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx);
	cmd_data_t _data;

	if (
		data == NULL ||
		data->data == NULL
	) {
		error = GPG_ERR_INV_DATA;
		goto cleanup;
	}

	/*
	 * Guess.. taken from openpgp card implementation
	 * and java PKCS#11 provider.
	 */
	_data.data = data->data;
	_data.size = data->size;
	if (
		*_data.data == 0 && (
			_data.size == 129 ||
			_data.size == 193 ||
			_data.size == 257 ||
			_data.size == 385 ||
			_data.size == 513
		)
	) {
		_data.data++;
		_data.size--;
	}

	if (
		(error = _get_certificate_by_name (
			ctx,
			line,
			OPENPGP_ENCR,
			&cert_id,
			NULL
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_create (
				cert_id,
				ctx,
				PKCS11H_PROMPT_MASK_ALLOW_ALL,
				PKCS11H_PIN_CACHE_INFINITE,
				&cert
			)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_lockSession (cert)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}
	session_locked = 1;

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_decryptAny (
				cert,
				CKM_RSA_PKCS, 
				_data.data,
				_data.size,
				NULL,
				&ptext_len
			)
		)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	if ((ptext = (unsigned char *)malloc (ptext_len)) == NULL) {
		error = GPG_ERR_ENOMEM;
		goto cleanup;
	}

	if (
		(error = common_map_pkcs11_error (
			pkcs11h_certificate_decryptAny (
				cert,
				CKM_RSA_PKCS, 
				_data.data,
				_data.size,
				ptext,
				&ptext_len
			)
		)) != GPG_ERR_NO_ERROR ||
		(error = assuan_write_status(ctx, "PADDING", "0")) != GPG_ERR_NO_ERROR ||
		(error = assuan_send_data(ctx, ptext, ptext_len)) != GPG_ERR_NO_ERROR
	) {
		goto cleanup;
	}

	error = GPG_ERR_NO_ERROR;

cleanup:

	if (session_locked) {
		pkcs11h_certificate_releaseSession (cert);
		session_locked = 0;
	}

	if (cert != NULL) {
		pkcs11h_certificate_freeCertificate (cert);
		cert = NULL;
	}

	if (cert_id != NULL) {
		pkcs11h_certificate_freeCertificateId (cert_id);
		cert_id = NULL;
	}

	if (ptext != NULL) {
		free (ptext);
		ptext = NULL;
	}

	return gpg_error (error);
}
Пример #9
0
int
pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
    struct tls_root_ctx * const ssl_ctx)
{
  int ret = 1;

  X509 *x509 = NULL;
  RSA *rsa = NULL;
  pkcs11h_openssl_session_t openssl_session = NULL;

  if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL)
    {
      msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
      goto cleanup;
    }

  /*
   * Will be released by openssl_session
   */
  certificate = NULL;

  if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL)
    {
      msg (M_WARN, "PKCS#11: Unable get rsa object");
      goto cleanup;
    }

  if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL)
    {
      msg (M_WARN, "PKCS#11: Unable get certificate object");
      goto cleanup;
    }

  if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx->ctx, rsa))
    {
      msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
      goto cleanup;
    }

  if (!SSL_CTX_use_certificate (ssl_ctx->ctx, x509))
    {
      msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
      goto cleanup;
    }
  ret = 0;

cleanup:
  /*
   * Certificate freeing is usually handled by openssl_session.
   * If something went wrong, creating the session we have to do it manually.
   */
  if (certificate != NULL) {
    pkcs11h_certificate_freeCertificate (certificate);
    certificate = NULL;
  }

  /*
   * openssl objects have reference
   * count, so release them
   */
  if (x509 != NULL)
    {
      X509_free (x509);
      x509 = NULL;
    }

  if (rsa != NULL)
    {
      RSA_free (rsa);
      rsa = NULL;
    }

  if (openssl_session != NULL)
    {
      pkcs11h_openssl_freeSession (openssl_session);
      openssl_session = NULL;
    }
  return ret;
}
Пример #10
0
int main () {
	pkcs11h_certificate_id_list_t issuers, certs, temp;
	pkcs11h_certificate_t cert;
	CK_RV rv;

	printf ("Initializing pkcs11-helper\n");

	if ((rv = pkcs11h_initialize ()) != CKR_OK) {
		fatal ("pkcs11h_initialize failed", rv);
	}

	printf ("Registering pkcs11-helper hooks\n");

	if ((rv = pkcs11h_setLogHook (_pkcs11h_hooks_log, NULL)) != CKR_OK) {
		fatal ("pkcs11h_setLogHook failed", rv);
	}

	pkcs11h_setLogLevel (TEST_LOG_LEVEL);

	if ((rv = pkcs11h_setTokenPromptHook (_pkcs11h_hooks_token_prompt, NULL)) != CKR_OK) {
		fatal ("pkcs11h_setTokenPromptHook failed", rv);
	}

	if ((rv = pkcs11h_setPINPromptHook (_pkcs11h_hooks_pin_prompt, NULL)) != CKR_OK) {
		fatal ("pkcs11h_setPINPromptHook failed", rv);
	}

	printf ("Adding provider '%s'\n", TEST_PROVIDER);

	if (
		(rv = pkcs11h_addProvider (
			TEST_PROVIDER,
			TEST_PROVIDER,
			FALSE,
			PKCS11H_PRIVATEMODE_MASK_AUTO,
			PKCS11H_SLOTEVENT_METHOD_AUTO,
			0,
			FALSE
		)) != CKR_OK
	) {
		fatal ("pkcs11h_addProvider failed", rv);
	}

	mypause ("Please remove all tokens, press <Enter>: ");

	printf ("Enumerating token certificate (list should be empty, no prompt)\n");

	if (
		(rv = pkcs11h_certificate_enumCertificateIds (
			PKCS11H_ENUM_METHOD_CACHE,
			NULL,
			PKCS11H_PROMPT_MASK_ALLOW_ALL,
			&issuers,
			&certs
		)) != CKR_OK
	) {
		fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
	}

	if (issuers != NULL || certs != NULL) {
		fatal ("No certificates should be found", rv);
	}

	mypause ("Please insert token, press <Enter>: ");

	printf ("Getting certificate cache, should be available certificates\n");

	if (
		(rv = pkcs11h_certificate_enumCertificateIds (
			PKCS11H_ENUM_METHOD_CACHE,
			NULL,
			PKCS11H_PROMPT_MASK_ALLOW_ALL,
			&issuers,
			&certs
		)) != CKR_OK
	) {
		fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
	}

	for (temp = issuers;temp != NULL;temp = temp->next) {
		printf ("Issuer: %s\n", temp->certificate_id->displayName);
	}
	for (temp = certs;temp != NULL;temp = temp->next) {
		printf ("Certificate: %s\n", temp->certificate_id->displayName);
	}

	if (certs == NULL) {
		fatal ("No certificates found", rv);
	}

	pkcs11h_certificate_freeCertificateIdList (issuers);
	pkcs11h_certificate_freeCertificateIdList (certs);

	mypause ("Please remove token, press <Enter>: ");

	printf ("Getting certificate cache, should be similar to last\n");

	if (
		(rv = pkcs11h_certificate_enumCertificateIds (
			PKCS11H_ENUM_METHOD_CACHE,
			NULL,
			PKCS11H_PROMPT_MASK_ALLOW_ALL,
			&issuers,
			&certs
		)) != CKR_OK
	) {
		fatal ("pkcs11h_certificate_enumCertificateIds failed", rv);
	}

	for (temp = issuers;temp != NULL;temp = temp->next) {
		printf ("Issuer: %s\n", temp->certificate_id->displayName);
	}
	for (temp = certs;temp != NULL;temp = temp->next) {
		printf ("Certificate: %s\n", temp->certificate_id->displayName);
	}

	if (certs == NULL) {
		fatal ("No certificates found", rv);
	}

	printf ("Creating certificate context\n");

	if (
		(rv = pkcs11h_certificate_create (
			certs->certificate_id,
			NULL,
			PKCS11H_PROMPT_MASK_ALLOW_ALL,
			PKCS11H_PIN_CACHE_INFINITE,
			&cert
		)) != CKR_OK
	) {
		fatal ("pkcs11h_certificate_create failed", rv);
	}

	printf ("Perforing signature #1 (you should be prompt for token and PIN)\n");

	sign_test (cert);

	printf ("Perforing signature #2 (you should NOT be prompt for anything)\n");

	sign_test (cert);

	mypause ("Please remove and insert token, press <Enter>: ");

	printf ("Perforing signature #3 (you should be prompt only for PIN)\n");

	sign_test (cert);

	printf ("Perforing signature #4 (you should NOT be prompt for anything)\n");

	if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) {
		fatal ("pkcs11h_certificate_free failed", rv);
	}

	if (
		(rv = pkcs11h_certificate_create (
			certs->certificate_id,
			NULL,
			PKCS11H_PROMPT_MASK_ALLOW_ALL,
			PKCS11H_PIN_CACHE_INFINITE,
			&cert
		)) != CKR_OK
	) {
		fatal ("pkcs11h_certificate_create failed", rv);
	}

	sign_test (cert);

	printf ("Terminating pkcs11-helper\n");

	if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) {
		fatal ("pkcs11h_certificate_free failed", rv);
	}

	pkcs11h_certificate_freeCertificateIdList (issuers);
	pkcs11h_certificate_freeCertificateIdList (certs);

	if ((rv = pkcs11h_terminate ()) != CKR_OK) {
		fatal ("pkcs11h_terminate failed", rv);
	}

	exit (0);
	return 0;
}
Пример #11
0
void vdb_mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key )
{
    if( NULL != priv_key )
        pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
}