Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
openssl
提交
bd59f2b9
O
openssl
项目概览
btwise
/
openssl
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
openssl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bd59f2b9
编写于
7月 20, 2013
作者:
D
Dr. Stephen Henson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
CMS RFC2631 X9.42 DH enveloped data support.
上级
dc1ce3bc
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
565 addition
and
9 deletion
+565
-9
crypto/dh/dh.h
crypto/dh/dh.h
+69
-0
crypto/dh/dh_ameth.c
crypto/dh/dh_ameth.c
+349
-1
crypto/dh/dh_err.c
crypto/dh/dh_err.c
+7
-1
crypto/dh/dh_pmeth.c
crypto/dh/dh_pmeth.c
+140
-7
未找到文件。
crypto/dh/dh.h
浏览文件 @
bd59f2b9
...
...
@@ -270,11 +270,74 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
#define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL)
#define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL)
#define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid)
#define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid)
#define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md)
#define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd)
#define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL)
#define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen)
#define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p)
#define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p)
#define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1)
#define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2)
#define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3)
#define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4)
#define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5)
#define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6)
#define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7)
#define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8)
#define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9)
#define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10)
#define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11)
#define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12)
#define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13)
#define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14)
/* KDF types */
#define EVP_PKEY_DH_KDF_NONE 1
#define EVP_PKEY_DH_KDF_X9_42 2
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
...
...
@@ -288,6 +351,9 @@ void ERR_load_DH_strings(void);
#define DH_F_COMPUTE_KEY 102
#define DH_F_DHPARAMS_PRINT_FP 101
#define DH_F_DH_BUILTIN_GENPARAMS 106
#define DH_F_DH_CMS_DECRYPT 114
#define DH_F_DH_CMS_SET_PEERKEY 115
#define DH_F_DH_CMS_SET_SHARED_INFO 116
#define DH_F_DH_NEW_METHOD 105
#define DH_F_DH_PARAM_DECODE 107
#define DH_F_DH_PRIV_DECODE 110
...
...
@@ -306,12 +372,15 @@ void ERR_load_DH_strings(void);
#define DH_R_BN_ERROR 106
#define DH_R_DECODE_ERROR 104
#define DH_R_INVALID_PUBKEY 102
#define DH_R_KDF_PARAMETER_ERROR 112
#define DH_R_KEYS_NOT_SET 108
#define DH_R_KEY_SIZE_TOO_SMALL 110
#define DH_R_MODULUS_TOO_LARGE 103
#define DH_R_NO_PARAMETERS_SET 107
#define DH_R_NO_PRIVATE_VALUE 100
#define DH_R_PARAMETER_ENCODING_ERROR 105
#define DH_R_PEER_KEY_ERROR 111
#define DH_R_SHARED_INFO_ERROR 113
#ifdef __cplusplus
}
...
...
crypto/dh/dh_ameth.c
浏览文件 @
bd59f2b9
...
...
@@ -62,6 +62,9 @@
#include <openssl/dh.h>
#include <openssl/bn.h>
#include "asn1_locl.h"
#ifndef OPENSSL_NO_CMS
#include <openssl/cms.h>
#endif
extern
const
EVP_PKEY_ASN1_METHOD
dhx_asn1_meth
;
...
...
@@ -569,6 +572,34 @@ int DHparams_print(BIO *bp, const DH *x)
return
do_dh_print
(
bp
,
x
,
4
,
NULL
,
0
);
}
#ifndef OPENSSL_NO_CMS
static
int
dh_cms_decrypt
(
CMS_RecipientInfo
*
ri
);
static
int
dh_cms_encrypt
(
CMS_RecipientInfo
*
ri
);
#endif
static
int
dh_pkey_ctrl
(
EVP_PKEY
*
pkey
,
int
op
,
long
arg1
,
void
*
arg2
)
{
switch
(
op
)
{
#ifndef OPENSSL_NO_CMS
case
ASN1_PKEY_CTRL_CMS_ENVELOPE
:
if
(
arg1
==
1
)
return
dh_cms_decrypt
(
arg2
);
else
if
(
arg1
==
0
)
return
dh_cms_encrypt
(
arg2
);
return
-
2
;
case
ASN1_PKEY_CTRL_CMS_RI_TYPE
:
*
(
int
*
)
arg2
=
CMS_RECIPINFO_AGREE
;
return
1
;
#endif
default:
return
-
2
;
}
}
const
EVP_PKEY_ASN1_METHOD
dh_asn1_meth
=
{
EVP_PKEY_DH
,
...
...
@@ -632,6 +663,323 @@ const EVP_PKEY_ASN1_METHOD dhx_asn1_meth =
0
,
int_dh_free
,
0
dh_pkey_ctrl
};
#ifndef OPENSSL_NO_CMS
static
int
dh_cms_set_peerkey
(
EVP_PKEY_CTX
*
pctx
,
X509_ALGOR
*
alg
,
ASN1_BIT_STRING
*
pubkey
)
{
ASN1_OBJECT
*
aoid
;
int
atype
;
void
*
aval
;
ASN1_INTEGER
*
public_key
;
int
rv
=
0
;
EVP_PKEY
*
pkpeer
=
NULL
,
*
pk
=
NULL
;
DH
*
dhpeer
=
NULL
;
const
unsigned
char
*
p
;
int
plen
;
X509_ALGOR_get0
(
&
aoid
,
&
atype
,
&
aval
,
alg
);
if
(
OBJ_obj2nid
(
aoid
)
!=
NID_dhpublicnumber
)
goto
err
;
/* Only absent parameters allowed in RFC XXXX */
if
(
atype
!=
V_ASN1_UNDEF
&&
atype
==
V_ASN1_NULL
)
goto
err
;
pk
=
EVP_PKEY_CTX_get0_pkey
(
pctx
);
if
(
!
pk
)
goto
err
;
if
(
pk
->
type
!=
EVP_PKEY_DHX
)
goto
err
;
/* Get parameters from parent key */
dhpeer
=
DHparams_dup
(
pk
->
pkey
.
dh
);
/* We have parameters now set public key */
plen
=
ASN1_STRING_length
(
pubkey
);
p
=
ASN1_STRING_data
(
pubkey
);
if
(
!
p
||
!
plen
)
goto
err
;
if
(
!
(
public_key
=
d2i_ASN1_INTEGER
(
NULL
,
&
p
,
plen
)))
{
DHerr
(
DH_F_DH_CMS_SET_PEERKEY
,
DH_R_DECODE_ERROR
);
goto
err
;
}
/* We have parameters now set public key */
if
(
!
(
dhpeer
->
pub_key
=
ASN1_INTEGER_to_BN
(
public_key
,
NULL
)))
{
DHerr
(
DH_F_DH_CMS_SET_PEERKEY
,
DH_R_BN_DECODE_ERROR
);
goto
err
;
}
pkpeer
=
EVP_PKEY_new
();
if
(
!
pkpeer
)
goto
err
;
EVP_PKEY_assign
(
pkpeer
,
pk
->
ameth
->
pkey_id
,
dhpeer
);
dhpeer
=
NULL
;
if
(
EVP_PKEY_derive_set_peer
(
pctx
,
pkpeer
)
>
0
)
rv
=
1
;
err:
if
(
public_key
)
ASN1_INTEGER_free
(
public_key
);
if
(
pkpeer
)
EVP_PKEY_free
(
pkpeer
);
if
(
dhpeer
)
DH_free
(
dhpeer
);
return
rv
;
}
static
int
dh_cms_set_shared_info
(
EVP_PKEY_CTX
*
pctx
,
CMS_RecipientInfo
*
ri
)
{
int
rv
=
0
;
X509_ALGOR
*
alg
,
*
kekalg
=
NULL
;
ASN1_OCTET_STRING
*
ukm
;
const
unsigned
char
*
p
;
unsigned
char
*
dukm
=
NULL
;
size_t
dukmlen
;
int
keylen
,
plen
;
const
EVP_CIPHER
*
kekcipher
;
EVP_CIPHER_CTX
*
kekctx
;
if
(
!
CMS_RecipientInfo_kari_get0_alg
(
ri
,
&
alg
,
&
ukm
))
goto
err
;
/* For DH we only have one OID permissible. If ever any more get
* defined we will need something cleverer.
*/
if
(
OBJ_obj2nid
(
alg
->
algorithm
)
!=
NID_id_smime_alg_ESDH
)
{
DHerr
(
DH_F_DH_CMS_SET_SHARED_INFO
,
DH_R_KDF_PARAMETER_ERROR
);
goto
err
;
}
if
(
EVP_PKEY_CTX_set_dh_kdf_type
(
pctx
,
EVP_PKEY_DH_KDF_X9_42
)
<=
0
)
goto
err
;
if
(
EVP_PKEY_CTX_set_dh_kdf_md
(
pctx
,
EVP_sha1
())
<=
0
)
goto
err
;
if
(
alg
->
parameter
->
type
!=
V_ASN1_SEQUENCE
)
goto
err
;
p
=
alg
->
parameter
->
value
.
sequence
->
data
;
plen
=
alg
->
parameter
->
value
.
sequence
->
length
;
kekalg
=
d2i_X509_ALGOR
(
NULL
,
&
p
,
plen
);
if
(
!
kekalg
)
goto
err
;
kekctx
=
CMS_RecipientInfo_kari_get0_ctx
(
ri
);
if
(
!
kekctx
)
goto
err
;
kekcipher
=
EVP_get_cipherbyobj
(
kekalg
->
algorithm
);
if
(
!
kekcipher
||
EVP_CIPHER_mode
(
kekcipher
)
!=
EVP_CIPH_WRAP_MODE
)
goto
err
;
if
(
!
EVP_EncryptInit_ex
(
kekctx
,
kekcipher
,
NULL
,
NULL
,
NULL
))
goto
err
;
if
(
EVP_CIPHER_asn1_to_param
(
kekctx
,
kekalg
->
parameter
)
<=
0
)
goto
err
;
keylen
=
EVP_CIPHER_CTX_key_length
(
kekctx
);
if
(
EVP_PKEY_CTX_set_dh_kdf_outlen
(
pctx
,
keylen
)
<=
0
)
goto
err
;
/* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
if
(
EVP_PKEY_CTX_set0_dh_kdf_oid
(
pctx
,
OBJ_nid2obj
(
EVP_CIPHER_type
(
kekcipher
)))
<=
0
)
goto
err
;
if
(
ukm
)
{
dukmlen
=
ASN1_STRING_length
(
ukm
);
dukm
=
BUF_memdup
(
ASN1_STRING_data
(
ukm
),
dukmlen
);
if
(
!
dukm
)
goto
err
;
}
if
(
EVP_PKEY_CTX_set0_dh_kdf_ukm
(
pctx
,
dukm
,
dukmlen
)
<=
0
)
goto
err
;
dukm
=
NULL
;
rv
=
1
;
err:
if
(
kekalg
)
X509_ALGOR_free
(
kekalg
);
if
(
dukm
)
OPENSSL_free
(
dukm
);
return
rv
;
}
static
int
dh_cms_decrypt
(
CMS_RecipientInfo
*
ri
)
{
EVP_PKEY_CTX
*
pctx
;
pctx
=
CMS_RecipientInfo_get0_pkey_ctx
(
ri
);
if
(
!
pctx
)
return
0
;
/* See if we need to set peer key */
if
(
!
EVP_PKEY_CTX_get0_peerkey
(
pctx
))
{
X509_ALGOR
*
alg
;
ASN1_BIT_STRING
*
pubkey
;
if
(
!
CMS_RecipientInfo_kari_get0_orig_id
(
ri
,
&
alg
,
&
pubkey
,
NULL
,
NULL
,
NULL
))
return
0
;
if
(
!
alg
||
!
pubkey
)
return
0
;
if
(
!
dh_cms_set_peerkey
(
pctx
,
alg
,
pubkey
))
{
DHerr
(
DH_F_DH_CMS_DECRYPT
,
DH_R_PEER_KEY_ERROR
);
return
0
;
}
}
/* Set DH derivation parameters and initialise unwrap context */
if
(
!
dh_cms_set_shared_info
(
pctx
,
ri
))
{
DHerr
(
DH_F_DH_CMS_DECRYPT
,
DH_R_SHARED_INFO_ERROR
);
return
0
;
}
return
1
;
}
static
int
dh_cms_encrypt
(
CMS_RecipientInfo
*
ri
)
{
EVP_PKEY_CTX
*
pctx
;
EVP_PKEY
*
pkey
;
EVP_CIPHER_CTX
*
ctx
;
int
keylen
;
X509_ALGOR
*
talg
,
*
wrap_alg
=
NULL
;
ASN1_OBJECT
*
aoid
;
ASN1_BIT_STRING
*
pubkey
;
ASN1_STRING
*
wrap_str
;
ASN1_OCTET_STRING
*
ukm
;
unsigned
char
*
penc
=
NULL
,
*
dukm
=
NULL
;
int
penclen
;
size_t
dukmlen
;
int
rv
=
0
;
int
kdf_type
,
wrap_nid
;
const
EVP_MD
*
kdf_md
;
pctx
=
CMS_RecipientInfo_get0_pkey_ctx
(
ri
);
if
(
!
pctx
)
return
0
;
/* Get ephemeral key */
pkey
=
EVP_PKEY_CTX_get0_pkey
(
pctx
);
if
(
!
CMS_RecipientInfo_kari_get0_orig_id
(
ri
,
&
talg
,
&
pubkey
,
NULL
,
NULL
,
NULL
))
goto
err
;
X509_ALGOR_get0
(
&
aoid
,
NULL
,
NULL
,
talg
);
/* Is everything uninitialised? */
if
(
aoid
==
OBJ_nid2obj
(
NID_undef
))
{
ASN1_INTEGER
*
pubk
;
pubk
=
BN_to_ASN1_INTEGER
(
pkey
->
pkey
.
dh
->
pub_key
,
NULL
);
if
(
!
pubk
)
goto
err
;
/* Set the key */
penclen
=
i2d_ASN1_INTEGER
(
pubk
,
&
penc
);
ASN1_INTEGER_free
(
pubk
);
if
(
penclen
<=
0
)
goto
err
;
ASN1_STRING_set0
(
pubkey
,
penc
,
penclen
);
pubkey
->
flags
&=
~
(
ASN1_STRING_FLAG_BITS_LEFT
|
0x07
);
pubkey
->
flags
|=
ASN1_STRING_FLAG_BITS_LEFT
;
penc
=
NULL
;
X509_ALGOR_set0
(
talg
,
OBJ_nid2obj
(
NID_dhpublicnumber
),
V_ASN1_UNDEF
,
NULL
);
}
/* See if custom paraneters set */
kdf_type
=
EVP_PKEY_CTX_get_dh_kdf_type
(
pctx
);
if
(
kdf_type
<=
0
)
goto
err
;
if
(
!
EVP_PKEY_CTX_get_dh_kdf_md
(
pctx
,
&
kdf_md
))
goto
err
;
if
(
kdf_type
==
EVP_PKEY_DH_KDF_NONE
)
{
kdf_type
=
EVP_PKEY_DH_KDF_X9_42
;
if
(
EVP_PKEY_CTX_set_dh_kdf_type
(
pctx
,
kdf_type
)
<=
0
)
goto
err
;
}
else
if
(
kdf_type
!=
EVP_PKEY_DH_KDF_X9_42
)
/* Unknown KDF */
goto
err
;
if
(
kdf_md
==
NULL
)
{
/* Only SHA1 supported */
kdf_md
=
EVP_sha1
();
if
(
EVP_PKEY_CTX_set_dh_kdf_md
(
pctx
,
kdf_md
)
<=
0
)
goto
err
;
}
else
if
(
EVP_MD_type
(
kdf_md
)
!=
NID_sha1
)
/* Unsupported digest */
goto
err
;
if
(
!
CMS_RecipientInfo_kari_get0_alg
(
ri
,
&
talg
,
&
ukm
))
goto
err
;
/* Get wrap NID */
ctx
=
CMS_RecipientInfo_kari_get0_ctx
(
ri
);
wrap_nid
=
EVP_CIPHER_CTX_type
(
ctx
);
if
(
EVP_PKEY_CTX_set0_dh_kdf_oid
(
pctx
,
OBJ_nid2obj
(
wrap_nid
))
<=
0
)
goto
err
;
keylen
=
EVP_CIPHER_CTX_key_length
(
ctx
);
/* Package wrap algorithm in an AlgorithmIdentifier */
wrap_alg
=
X509_ALGOR_new
();
if
(
!
wrap_alg
)
goto
err
;
wrap_alg
->
algorithm
=
OBJ_nid2obj
(
wrap_nid
);
wrap_alg
->
parameter
=
ASN1_TYPE_new
();
if
(
!
wrap_alg
->
parameter
)
goto
err
;
if
(
EVP_CIPHER_param_to_asn1
(
ctx
,
wrap_alg
->
parameter
)
<=
0
)
goto
err
;
if
(
ASN1_TYPE_get
(
wrap_alg
->
parameter
)
==
NID_undef
)
{
ASN1_TYPE_free
(
wrap_alg
->
parameter
);
wrap_alg
->
parameter
=
NULL
;
}
if
(
EVP_PKEY_CTX_set_dh_kdf_outlen
(
pctx
,
keylen
)
<=
0
)
goto
err
;
if
(
ukm
)
{
dukmlen
=
ASN1_STRING_length
(
ukm
);
dukm
=
BUF_memdup
(
ASN1_STRING_data
(
ukm
),
dukmlen
);
if
(
!
dukm
)
goto
err
;
}
if
(
EVP_PKEY_CTX_set0_dh_kdf_ukm
(
pctx
,
dukm
,
dukmlen
)
<=
0
)
goto
err
;
dukm
=
NULL
;
/* Now need to wrap encoding of wrap AlgorithmIdentifier into
* parameter of another AlgorithmIdentifier.
*/
penc
=
NULL
;
penclen
=
i2d_X509_ALGOR
(
wrap_alg
,
&
penc
);
if
(
!
penc
||
!
penclen
)
goto
err
;
wrap_str
=
ASN1_STRING_new
();
if
(
!
wrap_str
)
goto
err
;
ASN1_STRING_set0
(
wrap_str
,
penc
,
penclen
);
penc
=
NULL
;
X509_ALGOR_set0
(
talg
,
OBJ_nid2obj
(
NID_id_smime_alg_ESDH
),
V_ASN1_SEQUENCE
,
wrap_str
);
rv
=
1
;
err:
if
(
penc
)
OPENSSL_free
(
penc
);
if
(
wrap_alg
)
X509_ALGOR_free
(
wrap_alg
);
return
rv
;
}
#endif
crypto/dh/dh_err.c
浏览文件 @
bd59f2b9
/* crypto/dh/dh_err.c */
/* ====================================================================
* Copyright (c) 1999-201
0
The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-201
3
The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
...
...
@@ -73,6 +73,9 @@ static ERR_STRING_DATA DH_str_functs[]=
{
ERR_FUNC
(
DH_F_COMPUTE_KEY
),
"COMPUTE_KEY"
},
{
ERR_FUNC
(
DH_F_DHPARAMS_PRINT_FP
),
"DHparams_print_fp"
},
{
ERR_FUNC
(
DH_F_DH_BUILTIN_GENPARAMS
),
"DH_BUILTIN_GENPARAMS"
},
{
ERR_FUNC
(
DH_F_DH_CMS_DECRYPT
),
"DH_CMS_DECRYPT"
},
{
ERR_FUNC
(
DH_F_DH_CMS_SET_PEERKEY
),
"DH_CMS_SET_PEERKEY"
},
{
ERR_FUNC
(
DH_F_DH_CMS_SET_SHARED_INFO
),
"DH_CMS_SET_SHARED_INFO"
},
{
ERR_FUNC
(
DH_F_DH_NEW_METHOD
),
"DH_new_method"
},
{
ERR_FUNC
(
DH_F_DH_PARAM_DECODE
),
"DH_PARAM_DECODE"
},
{
ERR_FUNC
(
DH_F_DH_PRIV_DECODE
),
"DH_PRIV_DECODE"
},
...
...
@@ -94,12 +97,15 @@ static ERR_STRING_DATA DH_str_reasons[]=
{
ERR_REASON
(
DH_R_BN_ERROR
)
,
"bn error"
},
{
ERR_REASON
(
DH_R_DECODE_ERROR
)
,
"decode error"
},
{
ERR_REASON
(
DH_R_INVALID_PUBKEY
)
,
"invalid public key"
},
{
ERR_REASON
(
DH_R_KDF_PARAMETER_ERROR
)
,
"kdf parameter error"
},
{
ERR_REASON
(
DH_R_KEYS_NOT_SET
)
,
"keys not set"
},
{
ERR_REASON
(
DH_R_KEY_SIZE_TOO_SMALL
)
,
"key size too small"
},
{
ERR_REASON
(
DH_R_MODULUS_TOO_LARGE
)
,
"modulus too large"
},
{
ERR_REASON
(
DH_R_NO_PARAMETERS_SET
)
,
"no parameters set"
},
{
ERR_REASON
(
DH_R_NO_PRIVATE_VALUE
)
,
"no private value"
},
{
ERR_REASON
(
DH_R_PARAMETER_ENCODING_ERROR
),
"parameter encoding error"
},
{
ERR_REASON
(
DH_R_PEER_KEY_ERROR
)
,
"peer key error"
},
{
ERR_REASON
(
DH_R_SHARED_INFO_ERROR
)
,
"shared info error"
},
{
0
,
NULL
}
};
...
...
crypto/dh/dh_pmeth.c
浏览文件 @
bd59f2b9
...
...
@@ -65,6 +65,7 @@
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#include <openssl/objects.h>
#include "evp_locl.h"
/* DH pkey context structure */
...
...
@@ -76,11 +77,22 @@ typedef struct
int
generator
;
int
use_dsa
;
int
subprime_len
;
/* message digest used for parameter generation */
const
EVP_MD
*
md
;
int
rfc5114_param
;
/* Keygen callback info */
int
gentmp
[
2
];
/* message digest */
/* KDF (if any) to use for DH */
char
kdf_type
;
/* OID to use for KDF */
ASN1_OBJECT
*
kdf_oid
;
/* Message digest to use for key derivation */
const
EVP_MD
*
kdf_md
;
/* User key material */
unsigned
char
*
kdf_ukm
;
size_t
kdf_ukmlen
;
/* KDF output length */
size_t
kdf_outlen
;
}
DH_PKEY_CTX
;
static
int
pkey_dh_init
(
EVP_PKEY_CTX
*
ctx
)
...
...
@@ -96,6 +108,13 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx)
dctx
->
md
=
NULL
;
dctx
->
rfc5114_param
=
0
;
dctx
->
kdf_type
=
EVP_PKEY_DH_KDF_NONE
;
dctx
->
kdf_oid
=
NULL
;
dctx
->
kdf_md
=
NULL
;
dctx
->
kdf_ukm
=
NULL
;
dctx
->
kdf_ukmlen
=
0
;
dctx
->
kdf_outlen
=
0
;
ctx
->
data
=
dctx
;
ctx
->
keygen_info
=
dctx
->
gentmp
;
ctx
->
keygen_info_count
=
2
;
...
...
@@ -116,6 +135,18 @@ static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
dctx
->
use_dsa
=
sctx
->
use_dsa
;
dctx
->
md
=
sctx
->
md
;
dctx
->
rfc5114_param
=
sctx
->
rfc5114_param
;
dctx
->
kdf_type
=
sctx
->
kdf_type
;
dctx
->
kdf_oid
=
OBJ_dup
(
sctx
->
kdf_oid
);
if
(
!
dctx
->
kdf_oid
)
return
0
;
dctx
->
kdf_md
=
sctx
->
kdf_md
;
if
(
dctx
->
kdf_ukm
)
{
dctx
->
kdf_ukm
=
BUF_memdup
(
sctx
->
kdf_ukm
,
sctx
->
kdf_ukmlen
);
dctx
->
kdf_ukmlen
=
sctx
->
kdf_ukmlen
;
}
dctx
->
kdf_outlen
=
sctx
->
kdf_outlen
;
return
1
;
}
...
...
@@ -123,7 +154,13 @@ static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
{
DH_PKEY_CTX
*
dctx
=
ctx
->
data
;
if
(
dctx
)
{
if
(
dctx
->
kdf_ukm
)
OPENSSL_free
(
dctx
->
kdf_ukm
);
if
(
dctx
->
kdf_oid
)
ASN1_OBJECT_free
(
dctx
->
kdf_oid
);
OPENSSL_free
(
dctx
);
}
}
static
int
pkey_dh_ctrl
(
EVP_PKEY_CTX
*
ctx
,
int
type
,
int
p1
,
void
*
p2
)
...
...
@@ -170,6 +207,57 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
/* Default behaviour is OK */
return
1
;
case
EVP_PKEY_CTRL_DH_KDF_TYPE
:
if
(
p1
==
-
2
)
return
dctx
->
kdf_type
;
if
(
p1
!=
EVP_PKEY_DH_KDF_NONE
&&
p1
!=
EVP_PKEY_DH_KDF_X9_42
)
return
-
2
;
dctx
->
kdf_type
=
p1
;
return
1
;
case
EVP_PKEY_CTRL_DH_KDF_MD
:
dctx
->
kdf_md
=
p2
;
return
1
;
case
EVP_PKEY_CTRL_GET_DH_KDF_MD
:
*
(
const
EVP_MD
**
)
p2
=
dctx
->
kdf_md
;
return
1
;
case
EVP_PKEY_CTRL_DH_KDF_OUTLEN
:
if
(
p1
<=
0
)
return
-
2
;
dctx
->
kdf_outlen
=
(
size_t
)
p1
;
return
1
;
case
EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN
:
*
(
int
*
)
p2
=
dctx
->
kdf_outlen
;
return
1
;
case
EVP_PKEY_CTRL_DH_KDF_UKM
:
if
(
dctx
->
kdf_ukm
)
OPENSSL_free
(
dctx
->
kdf_ukm
);
dctx
->
kdf_ukm
=
p2
;
if
(
p2
)
dctx
->
kdf_ukmlen
=
p1
;
else
dctx
->
kdf_ukmlen
=
0
;
return
1
;
case
EVP_PKEY_CTRL_GET_DH_KDF_UKM
:
*
(
unsigned
char
**
)
p2
=
dctx
->
kdf_ukm
;
return
dctx
->
kdf_ukmlen
;
case
EVP_PKEY_CTRL_DH_KDF_OID
:
if
(
dctx
->
kdf_oid
)
ASN1_OBJECT_free
(
dctx
->
kdf_oid
);
dctx
->
kdf_oid
=
p2
;
return
1
;
case
EVP_PKEY_CTRL_GET_DH_KDF_OID
:
*
(
ASN1_OBJECT
**
)
p2
=
dctx
->
kdf_oid
;
return
1
;
default:
return
-
2
;
...
...
@@ -356,23 +444,68 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
static
int
pkey_dh_derive
(
EVP_PKEY_CTX
*
ctx
,
unsigned
char
*
key
,
size_t
*
keylen
)
{
int
ret
;
DH
*
dh
;
DH_PKEY_CTX
*
dctx
=
ctx
->
data
;
BIGNUM
*
dhpub
;
if
(
!
ctx
->
pkey
||
!
ctx
->
peerkey
)
{
DHerr
(
DH_F_PKEY_DH_DERIVE
,
DH_R_KEYS_NOT_SET
);
return
0
;
}
ret
=
DH_compute_key
(
key
,
ctx
->
peerkey
->
pkey
.
dh
->
pub_key
,
ctx
->
pkey
->
pkey
.
dh
);
if
(
ret
<
0
)
dh
=
ctx
->
pkey
->
pkey
.
dh
;
dhpub
=
ctx
->
peerkey
->
pkey
.
dh
->
pub_key
;
if
(
dctx
->
kdf_type
==
EVP_PKEY_DH_KDF_NONE
)
{
if
(
key
==
NULL
)
{
*
keylen
=
DH_size
(
dh
);
return
1
;
}
ret
=
DH_compute_key
(
key
,
dhpub
,
dh
);
if
(
ret
<
0
)
return
ret
;
*
keylen
=
ret
;
return
1
;
}
else
if
(
dctx
->
kdf_type
==
EVP_PKEY_DH_KDF_X9_42
)
{
unsigned
char
*
Z
=
NULL
;
size_t
Zlen
=
0
;
if
(
!
dctx
->
kdf_outlen
||
!
dctx
->
kdf_oid
)
return
0
;
if
(
key
==
NULL
)
{
*
keylen
=
dctx
->
kdf_outlen
;
return
1
;
}
if
(
*
keylen
!=
dctx
->
kdf_outlen
)
return
0
;
ret
=
0
;
Zlen
=
DH_size
(
dh
);
Z
=
OPENSSL_malloc
(
Zlen
);
if
(
DH_compute_key_padded
(
Z
,
dhpub
,
dh
)
<=
0
)
goto
err
;
if
(
!
DH_KDF_X9_42
(
key
,
*
keylen
,
Z
,
Zlen
,
dctx
->
kdf_oid
,
dctx
->
kdf_ukm
,
dctx
->
kdf_ukmlen
,
dctx
->
kdf_md
))
goto
err
;
*
keylen
=
dctx
->
kdf_outlen
;
ret
=
1
;
err:
if
(
Z
)
{
OPENSSL_cleanse
(
Z
,
Zlen
);
OPENSSL_free
(
Z
);
}
return
ret
;
*
keylen
=
ret
;
}
return
1
;
}
const
EVP_PKEY_METHOD
dh_pkey_meth
=
{
EVP_PKEY_DH
,
EVP_PKEY_FLAG_AUTOARGLEN
,
0
,
pkey_dh_init
,
pkey_dh_copy
,
pkey_dh_cleanup
,
...
...
@@ -408,7 +541,7 @@ const EVP_PKEY_METHOD dh_pkey_meth =
const
EVP_PKEY_METHOD
dhx_pkey_meth
=
{
EVP_PKEY_DHX
,
EVP_PKEY_FLAG_AUTOARGLEN
,
0
,
pkey_dh_init
,
pkey_dh_copy
,
pkey_dh_cleanup
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录