📄 asn1types.c
字号:
*/
status = VoltDecodeTagAndLen (
(VoltLibCtx *)0, encoding, length, &theTag, &lengthLen, &lenLo, &lenHi,
sizeof (unsigned int));
if (status != 0)
return (0);
valueLen = (unsigned int)lenLo;
/* Is the encoding big enough for the alleged lengths?
*/
totalLen = lengthLen + valueLen + 1;
if (length < (long)totalLen)
return (0);
/* Make sure the tag is OCTET STRING or IMPLICIT (if necessary).
*/
theTag = 4;
if (tag != -1)
theTag = aclass | tag;
if (encoding[0] != (unsigned char)theTag)
return (0);
encoding += (1 + lengthLen);
/* The OpenSSL engine requires moving the input pointer along.
*/
(*input) += totalLen;
/* If there is no algorithm object, just copy the data.
*/
if (value->cipherObj == (VtAlgorithmObject)0)
{
/* If copy by ref, copy the addresses, if copy by value, allocate and
* copy.
*/
if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
{
value->base.data = (unsigned char *)OPENSSL_malloc (valueLen);
if (value->base.data == (unsigned char *)0)
return (0);
Asn1Memcpy (value->base.data, encoding, valueLen);
}
else
{
value->base.data = encoding;
}
value->base.length = (int)valueLen;
return (1);
}
/* How long is the decrypted data.
*/
status = VtDecryptFinal (
value->cipherObj, value->random, encoding, valueLen,
(unsigned char *)0, 0, &decryptLen);
if (status != VT_ERROR_BUFFER_TOO_SMALL)
return (0);
/* At this point we can't copy by reference. Go ahead and allocate.
* Set the vFlags.
*/
if ((value->vFlags & VOLT_ASN1_COPY_MASK) != VOLT_ASN1_COPY_DATA)
{
value->vFlags ^= VOLT_ASN1_COPY_REFERENCE;
value->vFlags |= VOLT_ASN1_COPY_DATA;
}
value->base.data = (unsigned char *)OPENSSL_malloc (decryptLen);
if (value->base.data == (unsigned char *)0)
return (0);
status = VtDecryptFinal (
value->cipherObj, value->random, encoding, valueLen,
value->base.data, decryptLen, &decryptLen);
if (status != 0)
return (0);
value->base.length = (int)decryptLen;
/* Clear the context.
*/
ctx->valid = 0;
ctx->ret = 0;
ctx->plen = 0;
ctx->ptag = 0;
ctx->pclass = 0;
ctx->hdrlen = 0;
return (1);
}
int Asn1EncryptedContentEncode (
ASN1_VALUE **obj,
unsigned char **output,
const ASN1_ITEM *asn1Item,
int tag,
int aclass
)
{
int status;
unsigned int valueLen, totalLen, theTag;
Asn1EncryptedContent *value;
unsigned char *encoding;
if (obj == (ASN1_VALUE **)0)
return (0);
if (*obj == (ASN1_VALUE *)0)
return (0);
value = (Asn1EncryptedContent *)(*obj);
value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;
/* We can call this if the object is SET or has been initialized for
* Encryption/Encoding. Use totalLen as a temp variable.
*/
totalLen = VOLT_ENC_CONTENT_STATE_MASK & value->state;
if ( (totalLen == VOLT_ENC_CONTENT_STATE_CREATE) ||
(totalLen == VOLT_ENC_CONTENT_STATE_INIT_D) )
return (0);
if (totalLen == VOLT_ENC_CONTENT_STATE_SET)
{
status = VtEncryptInit (value->cipherObj, value->keyObj);
if (status != 0)
return (0);
value->state ^= totalLen;
value->state |= VOLT_ENC_CONTENT_STATE_INIT_E;
}
/* How big will the output be?
*/
status = VtEncryptFinal (
value->cipherObj, value->random, value->base.data,
(unsigned int)(value->base.length), (unsigned char *)0, 0, &valueLen);
if (status != VT_ERROR_BUFFER_TOO_SMALL)
return (0);
totalLen =
valueLen + VoltDetermineDerLengthLen ((UInt32)valueLen, (UInt32)0) + 1;
/* If there's no pointer to output, just indicate the length.
*/
if (output == (unsigned char **)0)
return (totalLen);
/* If the caller supplied no buffer, don't do anything.
*/
if (*output == (unsigned char *)0)
return (0);
/* If the caller supplied a pointer, but no buffer, don't do anything.
*/
if (*output == (unsigned char *)0)
return (0);
encoding = *output;
/* Write the tag and len. The tag is OCTET STRING, unless IMPLICIT.
*/
theTag = 4;
if (tag != -1)
theTag = aclass | tag;
encoding += VoltWriteDerTagAndLen (
encoding, theTag, (UInt32)valueLen, (UInt32)0);
/* Encrypt into the buffer.
*/
status = VtEncryptFinal (
value->cipherObj, value->random, value->base.data,
(unsigned int)(value->base.length), encoding, valueLen, &valueLen);
if (status != 0)
return (0);
/* The OpenSSL engine requires moving the output pointer along.
*/
(*output) += totalLen;
return (totalLen);
}
int Asn1CommonNew (
ASN1_VALUE **obj,
const ASN1_ITEM *asn1Item
)
{
VoltAsn1String *retVal = (VoltAsn1String *)0;
if (obj == (ASN1_VALUE **)0)
return (0);
*obj = (ASN1_VALUE *)0;
/* Build an empty VoltAsn1String struct.
*/
retVal = (VoltAsn1String *)OPENSSL_malloc (sizeof (VoltAsn1String));
if (retVal == (VoltAsn1String *)0)
return (0);
retVal->base.length = 0;
retVal->base.type = 0;
retVal->base.data = (unsigned char *)0;
retVal->base.flags = 0;
retVal->vFlags = 0;
*obj = (ASN1_VALUE *)retVal;
return (1);
}
void Asn1CommonFree (
ASN1_VALUE **obj,
const ASN1_ITEM *asn1Item
)
{
VoltAsn1String *value;
/* Anything to free?
*/
if (obj == (ASN1_VALUE **)0)
return;
if (*obj == (ASN1_VALUE *)0)
return;
value = (VoltAsn1String *)(*obj);
/* If copy by value, overwrite and free.
*/
if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
{
if (value->base.data != (unsigned char *)0)
{
Asn1Memset (value->base.data, 0, (unsigned int)(value->base.length));
OPENSSL_free (value->base.data);
}
}
OPENSSL_free (value);
*obj = (ASN1_VALUE *)0;
}
void Asn1CommonClear (
ASN1_VALUE **obj,
const ASN1_ITEM *asn1Item
)
{
VoltAsn1String *value;
/* Anything to free?
*/
if (obj == (ASN1_VALUE **)0)
return;
if (*obj == (ASN1_VALUE *)0)
return;
value = (VoltAsn1String *)(*obj);
/* If copy by value, overwrite and free.
*/
if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
{
if (value->base.data != (unsigned char *)0)
{
Asn1Memset (value->base.data, 0, (unsigned int)(value->base.length));
OPENSSL_free (value->base.data);
}
}
value->base.data = (unsigned char *)0;
value->base.length = 0;
}
int Asn1CommonSet (
VoltAsn1String *value,
unsigned char *data,
unsigned int len
)
{
if (value == (VoltAsn1String *)0)
return (0);
Asn1CommonClear ((ASN1_VALUE **)&value, (const ASN1_ITEM *)0);
value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;
if ( (data == (unsigned char *)0) || (len == 0) )
return (1);
/* If copy by ref, copy the addresses, if copy by value, allocate and
* copy.
*/
if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
{
value->base.data = (unsigned char *)OPENSSL_malloc (len);
if (value->base.data == (unsigned char *)0)
return (0);
Asn1Memcpy (value->base.data, data, len);
}
else
{
value->base.data = data;
}
value->base.length = len;
return (1);
}
int Asn1CommonDecode (
ASN1_VALUE **obj,
const unsigned char **input,
long length,
const ASN1_ITEM *asn1Item,
int tag,
int aclass,
char opt,
ASN1_TLC *ctx
)
{
int status, asn1Ret;
unsigned int lengthLen, valueLen, totalLen, theTag;
UInt32 lenLo, lenHi;
VoltAsn1String *value = (VoltAsn1String *)0;
unsigned char *encoding = (unsigned char *)(*input);
if (obj == (ASN1_VALUE **)0)
return (0);
if (*obj != (ASN1_VALUE *)0)
value = (VoltAsn1String *)(*obj);
Asn1CommonClear (obj, asn1Item);
/* What are the lengths?
*/
status = VoltDecodeTagAndLen (
(VoltLibCtx *)0, encoding, length, &theTag, &lengthLen, &lenLo, &lenHi,
sizeof (unsigned int));
if (status != 0)
return (0);
valueLen = (unsigned int)lenLo;
/* Is the encoding big enough for the alleged lengths?
*/
totalLen = lengthLen + valueLen + 1;
if (length < (long)totalLen)
return (0);
/* The OpenSSL engine requires moving the input pointer along.
*/
(*input) += totalLen;
/* If there is an underlying type, copy only the value. If not, copy
* everything.
*/
if (asn1Item->utype != 0)
{
/* Make sure the tag in the encoding is what we're expecting.
*/
theTag = (unsigned int)(asn1Item->utype);
if (tag != -1)
theTag = aclass | tag;
if (encoding[0] != (unsigned char)theTag)
return (0);
totalLen = valueLen;
encoding += (1 + lengthLen);
}
/* Is there an object? If not, create one.
*/
if (value == (VoltAsn1String *)0)
{
asn1Ret = Asn1CommonNew ((ASN1_VALUE **)&value, asn1Item);
if (asn1Ret != 1)
return (0);
*obj = (ASN1_VALUE *)value;
}
value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;
/* If copy by ref, copy the addresses, if copy by value, allocate and
* copy.
*/
if ((value->vFlags & VOLT_ASN1_COPY_MASK) == VOLT_ASN1_COPY_DATA)
{
/* Copy into the object.
*/
value->base.data = (unsigned char *)OPENSSL_malloc (totalLen);
if (value->base.data == (unsigned char *)0)
return (0);
Asn1Memcpy (value->base.data, encoding, totalLen);
}
else
{
value->base.data = encoding;
}
value->base.length = (int)totalLen;
/* Clear the context.
*/
ctx->valid = 0;
ctx->ret = 0;
ctx->plen = 0;
ctx->ptag = 0;
ctx->pclass = 0;
ctx->hdrlen = 0;
return (1);
}
int Asn1CommonEncode (
ASN1_VALUE **obj,
unsigned char **output,
const ASN1_ITEM *asn1Item,
int tag,
int aclass
)
{
unsigned int totalLen, theTag;
VoltAsn1String *value = (VoltAsn1String *)(*obj);
unsigned char *encoding;
value->vFlags |= VOLT_ASN1_COPY_FLAG_FIXED;
/* If there is an underlying type, encode the tag and length.
*/
totalLen = (unsigned int)(value->base.length);
if (asn1Item->utype != 0)
{
totalLen += VoltDetermineDerLengthLen ((UInt32)totalLen, (UInt32)0) + 1;
/* Is this implicit?
*/
theTag = (unsigned int)(asn1Item->utype);
if (tag != -1)
theTag = aclass | tag;
}
/* If there's no pointer to output, just indicate the length.
*/
if (output == (unsigned char **)0)
return (totalLen);
/* If the caller supplied no buffer, don't do anything.
*/
if (*output == (unsigned char *)0)
return (0);
encoding = *output;
/* If there is an underlying type, write the tag and len.
*/
if (asn1Item->utype != 0)
encoding += VoltWriteDerTagAndLen (
encoding, theTag, (UInt32)(value->base.length), (UInt32)0);
/* Simply copy the data into the buffer.
*/
if ( (value->base.data != (unsigned char *)0) && (value->base.length != 0) )
Asn1Memcpy (
encoding, value->base.data, (unsigned int)(value->base.length));
/* The OpenSSL engine requires moving the output pointer along.
*/
(*output) += totalLen;
return (totalLen);
}
void Asn1SetObjectCopyFlag (
VoltAsn1String *asn1Obj,
unsigned int copyFlag
)
{
unsigned int theFlag;
/* Examine only the COPY bits.
*/
theFlag = copyFlag & VOLT_ASN1_COPY_MASK;
if (asn1Obj == (VoltAsn1String *)0)
return;
/* If the vFlags says the copy flag is FIXED, don't do anything.
*/
if ((asn1Obj->vFlags & VOLT_ASN1_COPY_FLAG_FIXED) != 0)
return;
theFlag = VOLT_ASN1_COPY_DATA;
if (copyFlag != VOLT_ASN1_COPY_DATA)
theFlag = VOLT_ASN1_COPY_REFERENCE;
asn1Obj->vFlags |= theFlag;
}
void Asn1Memcpy (
unsigned char *dest,
unsigned char *source,
unsigned int count
)
{
unsigned int index;
if ( (source == (unsigned char *)0) ||
(dest == (unsigned char *)0) ||
(count == 0) )
return;
/* Not the most efficient, but portable (no system calls).
*/
for (index = 0; index < count; ++index)
dest[index] = source[index];
}
void Asn1Memset (
unsigned char *dest,
unsigned int value,
unsigned int count
)
{
unsigned int index;
unsigned char val;
if ( (dest == (unsigned char *)0) ||
(count == 0) )
return;
/* Not the most efficient, but portable (no system calls).
*/
val = (unsigned char)value;
for (index = 0; index < count; ++index)
dest[index] = val;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -