예제 #1
0
static bool
pkcs11_sign(void *pkcs11_cert, const void *src, size_t src_len,
            void *dst, size_t dst_len)
{
    return CKR_OK == pkcs11h_certificate_signAny(pkcs11_cert, CKM_RSA_PKCS,
                                                 src, src_len, dst, &dst_len);
}
예제 #2
0
void
sign_test (const pkcs11h_certificate_t cert) {

	static unsigned const char sha1_data[] = {
		0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, /* 1.3.14.3.2.26 */
		0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,	/* dummy data */
		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
		0x10, 0x11, 0x12, 0x13, 0x14
	};

	CK_RV rv;

	unsigned char *blob;
	size_t blob_size;

	if (
		(rv = pkcs11h_certificate_signAny (
			cert,
			CKM_RSA_PKCS,
			sha1_data,
			sizeof (sha1_data),
			NULL,
			&blob_size
		)) != CKR_OK
	) {
		fatal ("pkcs11h_certificate_sign(1) failed", rv);
	}

	blob = (unsigned char *)malloc (blob_size);

	if (
		(rv = pkcs11h_certificate_signAny (
			cert,
			CKM_RSA_PKCS,
			sha1_data,
			sizeof (sha1_data),
			blob,
			&blob_size
		)) != CKR_OK
	) {
		fatal ("pkcs11h_certificate_sign(1) failed", rv);
	}

	free (blob);
}
예제 #3
0
파일: pkcs11.c 프로젝트: LoganDing/pdns
int pkcs11_sign( pkcs11_context *ctx,
                    int mode,
                    int hash_id,
                    unsigned int hashlen,
                    const unsigned char *hash,
                    unsigned char *sig )
{
    size_t olen, asn_len;
    unsigned char *p = sig;

    if( NULL == ctx )
        return POLARSSL_ERR_RSA_BAD_INPUT_DATA;

    if( RSA_PUBLIC == mode )
        return POLARSSL_ERR_RSA_BAD_INPUT_DATA;

    olen = ctx->len;

    switch( hash_id )
    {
        case SIG_RSA_RAW:
            asn_len = 0;
            memcpy( p, hash, hashlen );
            break;

        case SIG_RSA_MD2:
            asn_len = OID_SIZE(ASN1_HASH_MDX);
            memcpy( p, ASN1_HASH_MDX, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[13] = 2; break;

        case SIG_RSA_MD4:
            asn_len = OID_SIZE(ASN1_HASH_MDX);
            memcpy( p, ASN1_HASH_MDX, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[13] = 4; break;

        case SIG_RSA_MD5:
            asn_len = OID_SIZE(ASN1_HASH_MDX);
            memcpy( p, ASN1_HASH_MDX, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[13] = 5; break;

        case SIG_RSA_SHA1:
            asn_len = OID_SIZE(ASN1_HASH_SHA1);
            memcpy( p, ASN1_HASH_SHA1, asn_len );
            memcpy( p + 15, hash, hashlen );
            break;

        case SIG_RSA_SHA224:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 4; p[18] += hashlen; break;

        case SIG_RSA_SHA256:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 1; p[18] += hashlen; break;

        case SIG_RSA_SHA384:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 2; p[18] += hashlen; break;

        case SIG_RSA_SHA512:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 3; p[18] += hashlen; break;

        default:
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
            asn_len + hashlen, sig, &olen ) != CKR_OK )
    {
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    return( 0 );
}
예제 #4
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);
}
예제 #5
0
static
ECDSA_SIG *
__pkcs11h_openssl_ecdsa_do_sign(
	IN const unsigned char *dgst,
	IN int dlen,
	IN const BIGNUM *inv,
	IN const BIGNUM *r,
	OUT EC_KEY *ec
) {
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_ecdsa_get_pkcs11h_certificate (ec);
	unsigned char *sigbuf = NULL;
	size_t siglen;
	ECDSA_SIG *sig = NULL;
	ECDSA_SIG *ret = NULL;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - entered dgst=%p, dlen=%d, inv=%p, r=%p, ec=%p",
		(void *)dgst,
		dlen,
		(void *)inv,
		(void *)r,
		(void *)ec
	);

	_PKCS11H_ASSERT (dgst!=NULL);
	_PKCS11H_ASSERT (inv==NULL);
	_PKCS11H_ASSERT (r==NULL);
	_PKCS11H_ASSERT (ec!=NULL);
	_PKCS11H_ASSERT (certificate!=NULL);

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_ECDSA,
			dgst,
			(size_t)dlen,
			NULL,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer");
		goto cleanup;
	}

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_ECDSA,
			dgst,
			(size_t)dlen,
			sigbuf,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((sig = ECDSA_SIG_new ()) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate ECDSA_SIG");
		goto cleanup;
	}

	if (BN_bin2bn (&sigbuf[0], siglen/2, sig->r) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa r");
		goto cleanup;
	}

	if (BN_bin2bn (&sigbuf[siglen/2], siglen/2, sig->s) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa s");
		goto cleanup;
	}

	ret = sig;
	sig = NULL;

cleanup:

	if (sigbuf != NULL) {
		_pkcs11h_mem_free ((void *)&sigbuf);
	}

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

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - return sig=%p",
		(void *)sig
	);

	return ret;
}
예제 #6
0
static
DSA_SIG *
__pkcs11h_openssl_dsa_do_sign(
	IN const unsigned char *dgst,
	IN int dlen,
	OUT DSA *dsa
) {
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_dsa_get_pkcs11h_certificate (dsa);
	unsigned char *sigbuf = NULL;
	size_t siglen;
	DSA_SIG *sig = NULL;
	DSA_SIG *ret = NULL;
	BIGNUM *r = NULL;
	BIGNUM *s = NULL;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_dsa_do_sign - entered dgst=%p, dlen=%d, dsa=%p",
		(void *)dgst,
		dlen,
		(void *)dsa
	);

	_PKCS11H_ASSERT (dgst!=NULL);
	_PKCS11H_ASSERT (dsa!=NULL);
	_PKCS11H_ASSERT (certificate!=NULL);

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_DSA,
			dgst,
			(size_t)dlen,
			NULL,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer");
		goto cleanup;
	}

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_DSA,
			dgst,
			(size_t)dlen,
			sigbuf,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((sig = DSA_SIG_new ()) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate DSA_SIG");
		goto cleanup;
	}

	if ((r = BN_bin2bn (&sigbuf[0], siglen/2, NULL)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa r");
		goto cleanup;
	}

	if ((s = BN_bin2bn (&sigbuf[siglen/2], siglen/2, NULL)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa s");
		goto cleanup;
	}

	DSA_SIG_set0 (sig, r, s);
	ret = sig;
	sig = NULL;
	r = NULL;
	s = NULL;

cleanup:

	if (sigbuf != NULL) {
		_pkcs11h_mem_free ((void *)&sigbuf);
	}

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

	if (r != NULL) {
		BN_clear_free (r);
	}

	if (s != NULL) {
		BN_clear_free (s);
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_dsa_do_sign - return sig=%p",
		(void *)sig
	);

	return ret;
}
예제 #7
0
static
int
__pkcs11h_openssl_rsa_enc (
	IN int flen,
	IN unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#else
static
int
__pkcs11h_openssl_rsa_enc (
	IN int flen,
	IN const unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#endif
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa);
	PKCS11H_BOOL session_locked = FALSE;
	CK_RV rv = CKR_FUNCTION_FAILED;
	size_t tlen;

	_PKCS11H_ASSERT (from!=NULL);
	_PKCS11H_ASSERT (to!=NULL);
	_PKCS11H_ASSERT (rsa!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_enc entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
		flen,
		from,
		to,
		(void *)rsa,
		padding
	);

	if (padding != RSA_PKCS1_PADDING) {
		rv = CKR_MECHANISM_INVALID;
		goto cleanup;
	}

	tlen = (size_t)RSA_size(rsa);

	if ((rv = pkcs11h_certificate_lockSession (certificate)) != CKR_OK) {
		goto cleanup;
	}
	session_locked = TRUE;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG1,
		"PKCS#11: Performing signature"
	);

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_RSA_PKCS,
			from,
			flen,
			to,
			&tlen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	rv = CKR_OK;

cleanup:

	if (session_locked) {
		pkcs11h_certificate_releaseSession (certificate);
		session_locked = FALSE;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_enc - return rv=%lu-'%s'",
		rv,
		pkcs11h_getMessage (rv)
	);

	return rv == CKR_OK ? (int)tlen : -1;
}
예제 #8
0
int pkcs11_sign( pkcs11_context *ctx,
                    int mode,
                    md_type_t md_alg,
                    unsigned int hashlen,
                    const unsigned char *hash,
                    unsigned char *sig )
{
    size_t sig_len = 0, asn_len = 0, oid_size = 0;
    unsigned char *p = sig;
    const char *oid;

    if( NULL == ctx )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    if( RSA_PRIVATE != mode )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    if( md_alg != POLARSSL_MD_NONE )
    {
        const md_info_t *md_info = md_info_from_type( md_alg );
        if( md_info == NULL )
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

        if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

        hashlen = md_get_size( md_info );
        asn_len = 10 + oid_size;
    }

    sig_len = ctx->len;
    if( hashlen > sig_len || asn_len > sig_len ||
        hashlen + asn_len > sig_len )
    {
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    if( md_alg != POLARSSL_MD_NONE )
    {
        /*
         * DigestInfo ::= SEQUENCE {
         *   digestAlgorithm DigestAlgorithmIdentifier,
         *   digest Digest }
         *
         * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
         *
         * Digest ::= OCTET STRING
         */
        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
        *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
        *p++ = (unsigned char) ( 0x04 + oid_size );
        *p++ = ASN1_OID;
        *p++ = oid_size & 0xFF;
        memcpy( p, oid, oid_size );
        p += oid_size;
        *p++ = ASN1_NULL;
        *p++ = 0x00;
        *p++ = ASN1_OCTET_STRING;
        *p++ = hashlen;
    }

    memcpy( p, hash, hashlen );

    if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
            asn_len + hashlen, sig, &sig_len ) != CKR_OK )
    {
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    return( 0 );
}