📄 dsakeyber.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "keyobj.h"
#include "oidlist.h"
#include "algid.h"
#include "prikeyder.h"
#include "pubkeyder.h"
#include "dsaparamsder.h"
#include "errorctx.h"
/* Set up the OpenSSL ASN.1 templates.
*/
ASN1_SEQUENCE (Asn1DsaParams) =
{
ASN1_SIMPLE (Asn1DsaParams, prime, ASN1_INTEGER),
ASN1_SIMPLE (Asn1DsaParams, subprime, ASN1_INTEGER),
ASN1_SIMPLE (Asn1DsaParams, base, ASN1_INTEGER)
} ASN1_SEQUENCE_END (Asn1DsaParams);
IMPLEMENT_ASN1_FUNCTIONS (Asn1DsaParams)
ASN1_SEQUENCE (Asn1DsaPubAndParams) =
{
ASN1_SIMPLE (Asn1DsaPubAndParams, pubVal, ASN1_INTEGER),
ASN1_SIMPLE (Asn1DsaPubAndParams, prime, ASN1_INTEGER),
ASN1_SIMPLE (Asn1DsaPubAndParams, subprime, ASN1_INTEGER),
ASN1_SIMPLE (Asn1DsaPubAndParams, base, ASN1_INTEGER)
} ASN1_SEQUENCE_END (Asn1DsaPubAndParams);
IMPLEMENT_ASN1_FUNCTIONS (Asn1DsaPubAndParams)
/* Build the params for the algID. The params for a DSA key (both
* public and private) are encoded as follows.
* SEQUENCE {
* prime INTEGER,
* subprime INTEGER,
* base INTEGER }
* <p>This function will allocate the memory needed to hold the
* encoding, it is the responsibility of the caller to free it (hence
* the word "Alloc" in the name).
*
* @param obj The object with the data to encode. It also contains the
* libCtx to use.
* @param paramData The param data (if hardware key, the data might not
* be in the object).
* @param encoding The address where the function will deposit the
* pointer to the allocated memory.
* @param encodingLen The address where this function will deposit the
* length, in bytes, of the encoding.
* @return an int, 0 if the function completed successfully or a
* non-zero error code (e.g., key and object don't match).
*/
static int VOLT_CALLING_CONV EncodeDsaParamsAlloc VOLT_PROTO_LIST ((
VoltKeyObject *obj,
VtDSAParamInfo *paramInfo,
unsigned char **encoding,
unsigned int *encodingLen
));
int VtDerCoderDSAPrivateKey (
VtDerCoderInfo *coderInfo,
Pointer object,
unsigned int flag
)
{
int status;
unsigned int bufferSize, paramsDerLen, keyValueLen;
VoltLibCtx *libCtx;
VoltKeyObject *obj = (VoltKeyObject *)object;
VoltDerCoderEncodeData *encodeData = &(coderInfo->info.encodeData);
VoltDerCoderGetAlgData *getAlgData = &(coderInfo->info.getAlgData);
VoltDerCoderDecodeData *decodeData = &(coderInfo->info.decodeData);
VtDSAPriKeyInfo *dsaKeyInfo;
Asn1PrivateKeyInfo *priKeyInfo;
unsigned char *paramsDer = (unsigned char *)0;
unsigned char *keyValue = (unsigned char *)0;
unsigned char *temp;
ASN1_INTEGER *value = (ASN1_INTEGER *)0;
Asn1DsaParams *dsaParams = (Asn1DsaParams *)0;
VtSetKeyBerInfo *setBerInfo;
VtDSAPriKeyInfo dsaPriKeyInfo;
unsigned char dsaKeyOid[VoltDsaKeyOidBytesLen] = { VoltDsaKeyOidBytes };
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
switch (flag)
{
default:
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
break;
case VOLT_DER_TYPE_ENCODE_FLAG:
/* If the flag is ENCODE, return the DSA Private Key inside a
* PKCS #8 PrivateKeyInfo.
*/
/* Check the args.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NON_NULL_ARG;
if (object != (Pointer)0)
break;
/* We need a place to drop the length.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (encodeData->encodingLen == (unsigned int *)0)
break;
/* The info should be a key object.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (encodeData->info == (Pointer)0)
break;
obj = (VoltKeyObject *)(encodeData->info);
/* We need the key data.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetKeyParam (
(VtKeyObject)obj, VtKeyParamDSAPrivate, (Pointer *)&dsaKeyInfo);
if (status != 0)
break;
/* If the previous call worked, we have a valid key object.
*/
libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
bufferSize = encodeData->bufferSize;
if (encodeData->encoding == (unsigned char *)0)
bufferSize = 0;
/* Create the encoding of the params. The dsaKeyInfo will look
* like paramInfo when cast.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = EncodeDsaParamsAlloc (
obj, (VtDSAParamInfo *)dsaKeyInfo, ¶msDer, ¶msDerLen);
if (status != 0)
break;
/* Build the encoding of the PrivateKey. For DSA private it is an
* INTEGER, the private value.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
value = ASN1_INTEGER_new ();
if (value == (ASN1_INTEGER *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_STRING_set (
value, dsaKeyInfo->priValX.data, dsaKeyInfo->priValX.len) != 1)
break;
/* The length of the encoding will likely be priValX.len plus 3
* bytes: 02 15 00 <priValX>.
* To be safe, allocate space for the priValX and for 7 extra
* bytes: 02 84 len len len len 00 <priValX>. This will probably
* never happen in the real world, but it saves coordinating code
* to max lengths of subprime.
*/
VOLT_SET_FNCT_LINE (fnctLine)
keyValue = (unsigned char *)Z2Malloc (
dsaKeyInfo->priValX.len + 7, VOLT_MEMORY_SENSITIVE);
if (keyValue == (unsigned char *)0)
break;
/* Encode.
*/
VOLT_SET_FNCT_LINE (fnctLine)
temp = keyValue;
keyValueLen = i2d_ASN1_INTEGER (value, &temp);
if (keyValueLen == 0)
break;
/* Encode PrivateKeyData.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltEncodePrivateKeyInfoDer (
libCtx, dsaKeyOid, VoltDsaKeyOidBytesLen, paramsDer, paramsDerLen,
keyValue, keyValueLen, encodeData->encoding, bufferSize,
encodeData->encodingLen);
break;
case VOLT_DER_TYPE_DECODE_FLAG:
/* If the flag is decode, set the key object with the private key
* info.
*/
/* Check the args, the type should be VOLT_DER_TYPE_PRI_KEY_FLAG.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
if (decodeData->type != VOLT_DER_TYPE_PRI_KEY_FLAG)
break;
/* Make sure this is the algId for DSA private key.
*/
VOLT_SET_FNCT_LINE (fnctLine)
priKeyInfo = (Asn1PrivateKeyInfo *)(decodeData->asn1Object);
if (priKeyInfo->algId->oid->base.length != VoltDsaKeyOidBytesLen)
break;
VOLT_SET_FNCT_LINE (fnctLine)
libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
if (Z2Memcmp (
priKeyInfo->algId->oid->base.data, dsaKeyOid,
VoltDsaKeyOidBytesLen) != 0)
break;
/* Decode the params if they're in the algID.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
dsaParams = Asn1DsaParams_new ();
if (dsaParams == (Asn1DsaParams *)0)
break;
/* Decode.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
temp = priKeyInfo->algId->params->base.data;
d2i_Asn1DsaParams (
&dsaParams, &temp, priKeyInfo->algId->params->base.length);
/* Did it work?
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (dsaParams == (Asn1DsaParams *)0)
break;
/* The encodedKey in the priKeyInfo should be an INTEGER.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
value = ASN1_INTEGER_new ();
if (value == (ASN1_INTEGER *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
temp = priKeyInfo->encodedKey->data;
d2i_ASN1_INTEGER (&value, &temp, priKeyInfo->encodedKey->length);
/* Did it work?
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (value == (ASN1_INTEGER *)0)
break;
setBerInfo = (VtSetKeyBerInfo *)(decodeData->info);
/* Build the struct needed to set a key object,
*/
dsaPriKeyInfo.primeP.data = dsaParams->prime->data;
dsaPriKeyInfo.primeP.len = dsaParams->prime->length;
dsaPriKeyInfo.subprimeQ.data = dsaParams->subprime->data;
dsaPriKeyInfo.subprimeQ.len = dsaParams->subprime->length;
dsaPriKeyInfo.baseG.data = dsaParams->base->data;
dsaPriKeyInfo.baseG.len = dsaParams->base->length;
dsaPriKeyInfo.pubValY.data = (unsigned char *)0;
dsaPriKeyInfo.pubValY.len = 0;
dsaPriKeyInfo.priValX.data = value->data;
dsaPriKeyInfo.priValX.len = value->length;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (
(VtKeyObject)obj, VtKeyParamDSAPrivate, (Pointer)&dsaPriKeyInfo);
break;
case VOLT_DER_TYPE_GET_ALG_FLAG:
/* If the flag is get alg, check the input to see if it's the
* DSA private key OID.
*/
/* Check the args.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NON_NULL_ARG;
if (object != (Pointer)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if ( (getAlgData->algorithm == (unsigned int *)0) ||
(getAlgData->oid == (unsigned char *)0) )
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
if (getAlgData->encodingType != VOLT_ENCODING_TYPE_PRI_KEY)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (getAlgData->oidLen != VoltDsaKeyOidBytesLen)
break;
VOLT_SET_FNCT_LINE (fnctLine)
libCtx = getAlgData->libCtx;
if (Z2Memcmp (
getAlgData->oid, dsaKeyOid, VoltDsaKeyOidBytesLen) != 0)
break;
/* The OID matches, the algorithm is DSA private key.
*/
*(getAlgData->algorithm) = VT_KEY_BER_DSA_PRIVATE;
getAlgData->SymKeyParam = (VtKeyParam *)0;
getAlgData->DigestImpl = (VtAlgorithmImpl *)0;
status = 0;
}
if (keyValue != (unsigned char *)0)
Z2Free (keyValue);
if (paramsDer != (unsigned char *)0)
Z2Free (paramsDer);
if (value != (ASN1_INTEGER *)0)
ASN1_INTEGER_free (value);
if (dsaParams != (Asn1DsaParams *)0)
Asn1DsaParams_free (dsaParams);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, object, status, 0, errorType,
(char *)0, "VtDerCoderDSAPrivateKey", fnctLine, (char *)0)
return (status);
}
int VtDerCoderDSAPublicKey (
VtDerCoderInfo *coderInfo,
Pointer object,
unsigned int flag
)
{
int status;
unsigned int bufferSize, paramsDerLen, keyValueLen;
VoltLibCtx *libCtx;
VoltKeyObject *obj = (VoltKeyObject *)object;
VoltDerCoderEncodeData *encodeData = &(coderInfo->info.encodeData);
VoltDerCoderGetAlgData *getAlgData = &(coderInfo->info.getAlgData);
VoltDerCoderDecodeData *decodeData = &(coderInfo->info.decodeData);
VtDSAPubKeyInfo *dsaKeyInfo;
Asn1SubjectPublicKey *subjPubKey;
unsigned char *paramsDer = (unsigned char *)0;
unsigned char *keyValue = (unsigned char *)0;
unsigned char *temp;
ASN1_INTEGER *value = (ASN1_INTEGER *)0;
Asn1DsaParams *dsaParams = (Asn1DsaParams *)0;
Asn1DsaPubAndParams *dsaPubAndParams = (Asn1DsaPubAndParams *)0;
VtSetKeyBerInfo *setBerInfo;
VtDSAPubKeyInfo dsaPubKeyInfo;
unsigned char dsaKeyOid[VoltDsaKeyOidBytesLen] = { VoltDsaKeyOidBytes };
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
obj = (VoltKeyObject *)object;
switch (flag)
{
default:
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -