📄 ibekeyber.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 "ibe.h"
#include "ibekeyber.h"
#include "prikeyder.h"
#include "errorctx.h"
/* Set up the OpenSSL ASN.1 templates.
*/
ASN1_SEQUENCE (Asn1IBEPrivateData) =
{
ASN1_SIMPLE (Asn1IBEPrivateData, format, Asn1ObjectId),
ASN1_SIMPLE (Asn1IBEPrivateData, value, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END (Asn1IBEPrivateData);
IMPLEMENT_ASN1_FUNCTIONS (Asn1IBEPrivateData)
ASN1_SEQUENCE (Asn1IBEPrivateKey) =
{
ASN1_OPT (Asn1IBEPrivateKey, version, ASN1_INTEGER),
ASN1_SIMPLE (Asn1IBEPrivateKey, privateData, Asn1IBEPrivateData),
ASN1_OPT (Asn1IBEPrivateKey, pubKey, Asn1Encoded),
ASN1_EXP_OPT (Asn1IBEPrivateKey, pubKeyDigest, Asn1Encoded, 0),
} ASN1_SEQUENCE_END (Asn1IBEPrivateKey);
IMPLEMENT_ASN1_FUNCTIONS (Asn1IBEPrivateKey)
int VoltEncodeIBEPrivateKeyData (
VoltKeyObject *obj,
VoltIBEPriKeyData *keyData
)
{
int status;
unsigned int pointLen, offset, encodingLen;
unsigned char *buffer = (unsigned char *)0;
unsigned char *temp;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
Asn1IBEPrivateKey *priKey = (Asn1IBEPrivateKey *)0;
unsigned char keyOid[VoltIBEPriKeyForm2OidBytesLen] =
{ VoltIBEPriKeyForm2OidBytes };
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If it's already computed, do nothing.
*/
if (obj->keyDer.data != (unsigned char *)0)
return (0);
do
{
/* Create the point, it needs to be
* 04 <xcoord> <ycoord>
* with both coordinates equal to the prime size.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
pointLen = (keyData->primeLen * 2) + 1;
buffer = (unsigned char *)Z2Malloc (pointLen, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
Z2Memset (buffer, 0, pointLen);
buffer[0] = 4;
/* If the xCoord is not as big as the prime, make sure we have
* leading 00 bytes.
*/
offset = keyData->primeLen - keyData->bfKeyInfo.privatePoint.xCoord.len;
offset++;
Z2Memcpy (
buffer + offset, keyData->bfKeyInfo.privatePoint.xCoord.data,
keyData->bfKeyInfo.privatePoint.xCoord.len);
/* Place the y-coordinate after x, leading 00 bytes if necessary.
*/
offset += keyData->bfKeyInfo.privatePoint.xCoord.len;
offset += (keyData->primeLen - keyData->bfKeyInfo.privatePoint.yCoord.len);
Z2Memcpy (
buffer + offset, keyData->bfKeyInfo.privatePoint.yCoord.data,
keyData->bfKeyInfo.privatePoint.yCoord.len);
/* Create the template.
*/
VOLT_SET_FNCT_LINE (fnctLine)
priKey = Asn1IBEPrivateKey_new ();
if (priKey == (Asn1IBEPrivateKey *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
priKey->version = ASN1_INTEGER_new ();
if (priKey->version == (ASN1_INTEGER *)0)
break;
/* Set the fields.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_INTEGER_set (priKey->version, 2) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1ObjectId_set (
priKey->privateData->format, keyOid, VoltIBEPriKeyForm2OidBytesLen) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_OCTET_STRING_set (
priKey->privateData->value, buffer, pointLen) != 1)
break;
/* Because it's optional, we have to create the pubKey.
*/
VOLT_SET_FNCT_LINE (fnctLine)
priKey->pubKey = Asn1Encoded_new ();
if (priKey->pubKey == (Asn1Encoded *)0)
break;
// Add code to differentiate between v1 and v2 (v2 is EXPLICIT)
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1Encoded_set (
priKey->pubKey, keyData->bfKeyInfo.encodedId.data,
keyData->bfKeyInfo.encodedId.len) != 1)
break;
/* How big does the buffer need to be?
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
encodingLen = i2d_Asn1IBEPrivateKey (priKey, (unsigned char **)0);
if (encodingLen == 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
Z2Free (buffer);
buffer = (unsigned char *)Z2Malloc (encodingLen, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
/* Now encode into the buffer.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
temp = buffer;
encodingLen = i2d_Asn1IBEPrivateKey (priKey, &temp);
if (encodingLen == 0)
break;
/* If successful, set the keyDer field.
*/
obj->keyDer.data = buffer;
obj->keyDer.len = encodingLen;
status = 0;
} while (0);
if (priKey != (Asn1IBEPrivateKey *)0)
Asn1IBEPrivateKey_free (priKey);
/* If successful, we're done.
*/
if (status == 0)
return (0);
/* If there was an error, free the buffer.
*/
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR_INFO (
0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VoltEncodeIBEPrivateKeyData", fnctLine, (char *)0)
return (status);
}
int VoltDecodeIBEPriKeyDataCreate (
VoltLibCtx *libCtx,
unsigned char *encoding,
unsigned int maxEncodingLen,
Asn1IBEPrivateKey **ibeKey
)
{
int status;
Asn1IBEPrivateKey *newIBEKey = (Asn1IBEPrivateKey *)0;
unsigned char *temp;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Create the Asn1 object.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
newIBEKey = Asn1IBEPrivateKey_new ();
/* Try to decode.
*/
status = VT_ERROR_UNKNOWN_BER;
temp = encoding;
d2i_Asn1IBEPrivateKey (&newIBEKey, &temp, maxEncodingLen);
/* Did it work?
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (newIBEKey == (Asn1IBEPrivateKey *)0)
break;
/* If successful, return the object.
*/
*ibeKey = newIBEKey;
status = 0;
} while (0);
/* If no error, we're done.
*/
if (status == 0)
return (0);
/* If there was an error, destroy what we created.
*/
if (newIBEKey != (Asn1IBEPrivateKey *)0)
Asn1IBEPrivateKey_free (newIBEKey);
VOLT_LOG_ERROR_INFO (
libCtx, 0, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VoltDecodeIBEPriKeyDataCreate", fnctLine, (char *)0)
return (status);
}
int VoltIBEPriPointFromEncodingAlloc (
VoltLibCtx *libCtx,
VoltParameterObject *pObj,
Asn1IBEPrivateData *priData,
VtBFType1IBEPoint **ibePoint
)
{
int status;
unsigned int primeLen, bufferSize, offset, coordCount, xFlag;
unsigned char *buffer = (unsigned char *)0;
VoltBFType1IBEParams *theParams = (VoltBFType1IBEParams *)(pObj->paramData);
unsigned char f1Oid[VoltIBEPriKeyForm1OidBytesLen] =
{ VoltIBEPriKeyForm1OidBytes };
unsigned char f2Oid[VoltIBEPriKeyForm2OidBytesLen] =
{ VoltIBEPriKeyForm2OidBytes };
VtBFType1IBEPoint *newPoint = (VtBFType1IBEPoint *)0;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Initialize coordCount to 1, meaning only one coordinate is
* given in the encoding. If two coordinates are given, change it.
*/
coordCount = 1;
/* How big is the prime?
*/
primeLen = theParams->paramInfo.curve.primeP.len;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
/* Make sure the OID is recognized.
* If xFlag is 1, only xCoord is given.
* If 2, only yCoord is given.
* If 3, both.
*/
if (priData->format->base.length == VoltIBEPriKeyForm1OidBytesLen)
{
if (Z2Memcmp (
priData->format->base.data, f1Oid, VoltIBEPriKeyForm1OidBytesLen) == 0)
{
/* If v.1, the length should be primeLen + 1, but it might be
* primeLen.
*/
xFlag = 1;
if ((unsigned int)(priData->value->length) == primeLen)
xFlag = 2;
else if ((unsigned int)(priData->value->length) != (primeLen + 1))
break;
status = 0;
}
}
/* If it wasn't Format v.1, check for v.2.
*/
if (status != 0)
{
/* If we reach this point, status is VT_ERROR_UNKNOWN_BER and the
* OID is not v.1. If not v.2, error.
*/
if (priData->format->base.length != VoltIBEPriKeyForm2OidBytesLen)
break;
if (Z2Memcmp (
priData->format->base.data, f2Oid, VoltIBEPriKeyForm2OidBytesLen) != 0)
break;
/* If v.2, the length should be (2 * primeLen) + 1.
*/
if ((unsigned int)(priData->value->length) != ((2 * primeLen) + 1))
break;
coordCount = 2;
xFlag = 3;
}
/* Build a buffer to hold the Point struct and either one or two
* coordinates, depending on how many are given. Add an extra byte
* in case of format 1.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
bufferSize = sizeof (VtBFType1IBEPoint) + (coordCount * primeLen) + 1;
buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
newPoint = (VtBFType1IBEPoint *)buffer;
Z2Memset (buffer, 0, bufferSize);
offset = sizeof (VtBFType1IBEPoint);
/* Locate the pointers.
*/
if ((xFlag & 1) == 1)
{
newPoint->xCoord.data = buffer + offset;
offset += primeLen + 1;
}
if ((xFlag & 2) == 2)
{
newPoint->yCoord.data = buffer + offset;
}
if (coordCount == 1)
{
if (xFlag == 1)
{
Z2Memcpy (newPoint->xCoord.data, priData->value->data, primeLen + 1);
newPoint->xCoord.len = primeLen + 1;
}
else
{
Z2Memcpy (newPoint->yCoord.data, priData->value->data, primeLen);
newPoint->yCoord.len = primeLen;
}
}
else
{
/* Just copy the coordinates.
*/
Z2Memcpy (newPoint->xCoord.data, priData->value->data + 1, primeLen);
newPoint->xCoord.len = primeLen;
Z2Memcpy (
newPoint->yCoord.data, priData->value->data + primeLen + 1, primeLen);
newPoint->yCoord.len = primeLen;
}
*ibePoint = newPoint;
status = 0;
} while (0);
/* If success, we're done.
*/
if (status == 0)
return (0);
/* If error, free what we allocated.
*/
if (newPoint != (VtBFType1IBEPoint *)0)
Z2Free (newPoint);
VOLT_LOG_ERROR_INFO (
libCtx, pObj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VoltIBEPriPointFromEncodingAlloc", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -