Support for digest signing and X931 in rsa_pkey_meth.

This commit is contained in:
Dr. Stephen Henson 2006-04-09 19:17:25 +00:00
parent 6471c9f478
commit b2a97be7f4
7 changed files with 174 additions and 11 deletions

View File

@ -914,6 +914,10 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
#define EVP_PKEY_OP_ENCRYPT 8
#define EVP_PKEY_OP_DECRYPT 9
#define EVP_PKEY_CTRL_MD_NID 1
#define EVP_PKEY_ALG_CTRL 0x1000
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey);
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
@ -1024,6 +1028,7 @@ void ERR_load_EVP_strings(void);
#define EVP_R_EXPECTING_A_EC_KEY 142
#define EVP_R_INITIALIZATION_ERROR 134
#define EVP_R_INPUT_NOT_INITIALIZED 111
#define EVP_R_INVALID_DIGEST 152
#define EVP_R_INVALID_KEY_LENGTH 130
#define EVP_R_INVALID_OPERATION 148
#define EVP_R_IV_TOO_LARGE 102

View File

@ -143,6 +143,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"},
{ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"},
{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
{ERR_REASON(EVP_R_INVALID_DIGEST) ,"invalid digest"},
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
{ERR_REASON(EVP_R_INVALID_OPERATION) ,"invalid operation"},
{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},

View File

@ -179,5 +179,16 @@ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
if (!strcmp(name, "digest"))
{
const EVP_MD *md;
if (!value || !(md = EVP_get_digestbyname(value)))
{
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_DIGEST);
return 0;
}
return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_MD_NID,
EVP_MD_type(md), NULL);
}
return ctx->pmeth->ctrl_str(ctx, name, value);
}

View File

@ -196,7 +196,7 @@ struct rsa_st
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
pad, NULL)
#define EVP_PKEY_CTRL_RSA_PADDING 1
#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
#define RSA_PKCS1_PADDING 1
#define RSA_SSLV23_PADDING 2
@ -349,7 +349,9 @@ void ERR_load_RSA_strings(void);
/* Error codes for the RSA functions. */
/* Function codes. */
#define RSA_F_CHECK_PADDING_NID 140
#define RSA_F_MEMORY_LOCK 100
#define RSA_F_PKEY_RSA_VERIFYRECOVER 141
#define RSA_F_RSA_BUILTIN_KEYGEN 129
#define RSA_F_RSA_CHECK_KEY 123
#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101
@ -409,10 +411,13 @@ void ERR_load_RSA_strings(void);
#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125
#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123
#define RSA_R_FIRST_OCTET_INVALID 133
#define RSA_R_INVALID_DIGEST 105
#define RSA_R_INVALID_HEADER 137
#define RSA_R_INVALID_MESSAGE_LENGTH 131
#define RSA_R_INVALID_PADDING 138
#define RSA_R_INVALID_PADDING_MODE 141
#define RSA_R_INVALID_TRAILER 139
#define RSA_R_INVALID_X931_DIGEST 142
#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126
#define RSA_R_KEY_SIZE_TOO_SMALL 120
#define RSA_R_LAST_OCTET_INVALID 134

View File

@ -70,7 +70,9 @@
static ERR_STRING_DATA RSA_str_functs[]=
{
{ERR_FUNC(RSA_F_CHECK_PADDING_NID), "CHECK_PADDING_NID"},
{ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"},
{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"},
{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
@ -100,7 +102,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"},
{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_PRINT_FP"},
{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"},
{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"},
{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
@ -133,10 +135,13 @@ static ERR_STRING_DATA RSA_str_reasons[]=
{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
{ERR_REASON(RSA_R_FIRST_OCTET_INVALID) ,"first octet invalid"},
{ERR_REASON(RSA_R_INVALID_DIGEST) ,"invalid digest"},
{ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"},
{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
{ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"},
{ERR_REASON(RSA_R_INVALID_PADDING_MODE) ,"invalid padding mode"},
{ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"},
{ERR_REASON(RSA_R_INVALID_X931_DIGEST) ,"invalid x931 digest"},
{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"},

View File

@ -60,8 +60,14 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include "evp_locl.h"
extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
unsigned char *rm, unsigned int *prm_len,
unsigned char *sigbuf, unsigned int siglen,
RSA *rsa);
/* RSA pkey context structure */
typedef struct
@ -71,6 +77,10 @@ typedef struct
BIGNUM *pub_exp;
/* RSA padding mode */
int pad_mode;
/* nid for message digest */
int md_nid;
/* Temp buffer */
unsigned char *tbuf;
} RSA_PKEY_CTX;
static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
@ -82,7 +92,21 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
rctx->nbits = 1024;
rctx->pub_exp = NULL;
rctx->pad_mode = RSA_PKCS1_PADDING;
rctx->md_nid = NID_undef;
rctx->tbuf = NULL;
ctx->data = rctx;
return 1;
}
static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
{
if (ctx->tbuf)
return 1;
ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
if (!ctx->tbuf)
return 0;
return 1;
}
@ -102,7 +126,31 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
if (rctx->md_nid != NID_undef)
{
if (rctx->pad_mode == RSA_X931_PADDING)
{
if (!setup_tbuf(rctx, ctx))
return -1;
memcpy(rctx->tbuf, tbs, tbslen);
rctx->tbuf[tbslen] = RSA_X931_hash_id(rctx->md_nid);
ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
sig, ctx->pkey->pkey.rsa,
RSA_X931_PADDING);
}
else if (rctx->pad_mode == RSA_PKCS1_PADDING)
{
unsigned int sltmp;
ret = RSA_sign(rctx->md_nid, tbs, tbslen, sig, &sltmp,
ctx->pkey->pkey.rsa);
}
else
return -1;
}
else
ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
rctx->pad_mode);
if (ret < 0)
return ret;
@ -117,7 +165,38 @@ static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
ret = RSA_public_decrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
if (rctx->md_nid != NID_undef)
{
if (rctx->pad_mode == RSA_X931_PADDING)
{
if (!setup_tbuf(rctx, ctx))
return -1;
ret = RSA_private_encrypt(tbslen, tbs,
rctx->tbuf, ctx->pkey->pkey.rsa,
RSA_X931_PADDING);
if (ret < 1)
return 0;
if (rctx->tbuf[ret] != RSA_X931_hash_id(rctx->md_nid))
{
RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
RSA_R_ALGORITHM_MISMATCH);
return 0;
}
ret--;
memcpy(sig, rctx->tbuf, ret);
}
else if (rctx->pad_mode == RSA_PKCS1_PADDING)
{
unsigned int sltmp;
ret = int_rsa_verify(rctx->md_nid, NULL, 0, sig, &sltmp,
tbs, tbslen, ctx->pkey->pkey.rsa);
}
else
return -1;
}
else
ret = RSA_public_decrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
rctx->pad_mode);
if (ret < 0)
return ret;
@ -151,23 +230,55 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
return 1;
}
static int check_padding_nid(int nid, int padding)
{
if (nid == NID_undef)
return 1;
if (padding == RSA_NO_PADDING)
{
RSAerr(RSA_F_CHECK_PADDING_NID, RSA_R_INVALID_PADDING_MODE);
return 0;
}
if (padding == RSA_X931_PADDING)
{
if (RSA_X931_hash_id(nid) == -1)
{
RSAerr(RSA_F_CHECK_PADDING_NID,
RSA_R_INVALID_X931_DIGEST);
return 0;
}
return 1;
}
return 1;
}
static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
RSA_PKEY_CTX *rctx = ctx->data;
switch (type)
{
case EVP_PKEY_CTRL_RSA_PADDING:
/* TODO: add PSS support */
if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_X931_PADDING))
{
if (ctx->operation == EVP_PKEY_OP_KEYGEN)
return -2;
if (!check_padding_nid(rctx->md_nid, p1))
return 0;
rctx->pad_mode = p1;
return 1;
}
return -2;
case EVP_PKEY_CTRL_MD_NID:
if (!check_padding_nid(p1, rctx->pad_mode))
return 0;
rctx->md_nid = p1;
return 1;
default:
return -2;

View File

@ -142,8 +142,10 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
return(ret);
}
int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
unsigned char *rm, unsigned int *prm_len,
unsigned char *sigbuf, unsigned int siglen,
RSA *rsa)
{
int i,ret=0,sigtype;
unsigned char *s;
@ -155,10 +157,14 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
return(0);
}
if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
if((dtype == NID_md5_sha1) && rm)
{
return rsa->meth->rsa_verify(dtype, m, m_len,
sigbuf, siglen, rsa);
i = RSA_public_decrypt((int)siglen,
sigbuf,rm,rsa,RSA_PKCS1_PADDING);
if (i <= 0)
return 0;
*prm_len = i;
return 1;
}
s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
@ -212,7 +218,13 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
goto err;
}
}
if ( ((unsigned int)sig->digest->length != m_len) ||
if (rm)
{
memcpy(rm, sig->digest->data, sig->digest->length);
*prm_len = sig->digest->length;
ret = 1;
}
else if (((unsigned int)sig->digest->length != m_len) ||
(memcmp(m,sig->digest->data,m_len) != 0))
{
RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
@ -230,3 +242,16 @@ err:
return(ret);
}
int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen,
RSA *rsa)
{
if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
{
return rsa->meth->rsa_verify(dtype, m, m_len,
sigbuf, siglen, rsa);
}
return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
}