fix for bug 115360, ASN.1 encoder/decoder should handle conversion of unsigned integers used in NSS to ASN.1 INTEGERs, and vice versa.

This commit is contained in:
ian.mcgreer%sun.com 2002-01-14 23:20:43 +00:00
Родитель 716b8f0319
Коммит a29542b7fa
4 изменённых файлов: 58 добавлений и 35 удалений

Просмотреть файл

@ -634,26 +634,21 @@ PK11_GetKeyData(PK11SymKey *symKey)
}
/*
* take an attribute and copy it into a secitem, converting unsigned to signed.
* take an attribute and copy it into a secitem
*/
static CK_RV
pk11_Attr2SecItem(PRArenaPool *arena, CK_ATTRIBUTE *attr, SECItem *item) {
unsigned char *dataPtr;
pk11_Attr2SecItem(PRArenaPool *arena, CK_ATTRIBUTE *attr, SECItem *item)
{
item->data = NULL;
item->len = attr->ulValueLen;
dataPtr = (unsigned char*) PORT_ArenaAlloc(arena, item->len+1);
if ( dataPtr == NULL) {
(void)SECITEM_AllocItem(arena, item, attr->ulValueLen);
if (item->data == NULL) {
return CKR_HOST_MEMORY;
}
*dataPtr = 0;
item->data = dataPtr+1;
PORT_Memcpy(item->data,attr->pValue,item->len);
if (item->data[0] & 0x80) {
item->data = item->data-1;
item->len++;
}
PORT_Memcpy(item->data, attr->pValue, item->len);
return CKR_OK;
}
/*
* extract a public key from a slot and id
*/

Просмотреть файл

@ -1165,40 +1165,27 @@ pk11_AddAttribute(PK11Object *object,PK11Attribute *attribute)
}
/*
* copy an unsigned attribute into a 'signed' SECItem. Secitem is allocated in
* copy an unsigned attribute into a SECItem. Secitem is allocated in
* the specified arena.
*/
CK_RV
pk11_Attribute2SSecItem(PLArenaPool *arena,SECItem *item,PK11Object *object,
CK_ATTRIBUTE_TYPE type)
{
int len;
PK11Attribute *attribute;
unsigned char *start;
int real_len;
item->data = NULL;
attribute = pk11_FindAttribute(object, type);
if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
real_len = len = attribute->attrib.ulValueLen;
if ((*((unsigned char *)attribute->attrib.pValue) & 0x80) != 0) {
real_len++;
}
if (arena) {
start = item->data = (unsigned char *) PORT_ArenaAlloc(arena,real_len);
} else {
start = item->data = (unsigned char *) PORT_Alloc(real_len);
}
(void)SECITEM_AllocItem(arena, item, attribute->attrib.ulValueLen);
if (item->data == NULL) {
pk11_FreeAttribute(attribute);
return CKR_HOST_MEMORY;
}
item->len = real_len;
if (real_len != len) {
*start = 0;
start++;
}
PORT_Memcpy(start, attribute->attrib.pValue, len);
PORT_Memcpy(item->data, attribute->attrib.pValue, item->len);
pk11_FreeAttribute(attribute);
return CKR_OK;
}

Просмотреть файл

@ -35,7 +35,7 @@
* Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished
* Encoding Rules).
*
* $Id: secasn1d.c,v 1.13 2002/01/11 00:33:08 relyea%netscape.com Exp $
* $Id: secasn1d.c,v 1.14 2002/01/14 23:20:42 ian.mcgreer%sun.com Exp $
*/
#include "secasn1.h"
@ -1324,6 +1324,7 @@ sec_asn1d_parse_leaf (sec_asn1d_state *state,
const char *buf, unsigned long len)
{
SECItem *item;
unsigned long bufLen;
if (len == 0) {
state->top->status = needBytes;
@ -1333,16 +1334,27 @@ sec_asn1d_parse_leaf (sec_asn1d_state *state,
if (state->pending < len)
len = state->pending;
bufLen = len;
item = (SECItem *)(state->dest);
if (item != NULL && item->data != NULL) {
/* Strip leading zeroes */
if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */
item->len == 0) /* MSB */
{
while (len > 1 && buf[0] == 0) { /* leading 0 */
buf++;
len--;
}
}
PORT_Memcpy (item->data + item->len, buf, len);
item->len += len;
}
state->pending -= len;
state->pending -= bufLen;
if (state->pending == 0)
state->place = beforeEndOfContents;
return len;
return bufLen;
}

Просмотреть файл

@ -35,7 +35,7 @@
* Support for ENcoding ASN.1 data based on BER/DER (Basic/Distinguished
* Encoding Rules).
*
* $Id: secasn1e.c,v 1.4 2001/08/03 00:37:53 javi%netscape.com Exp $
* $Id: secasn1e.c,v 1.5 2002/01/14 23:20:43 ian.mcgreer%sun.com Exp $
*/
#include "secasn1.h"
@ -684,6 +684,17 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
len++;
break;
case SEC_ASN1_INTEGER:
/* ASN.1 INTEGERs are signed. PKCS#11 BigIntegers are unsigned. NSS
* will treat numbers going in and out of the ASN.1 encoder as
* unsigned, so the encoder must handle the conversion.
*/
len = ((SECItem *)src)->len;
if (len > 0 && ((SECItem *)src)->data[0] & 0x80) {
len++; /* will add leading 0 */
}
break;
default:
len = ((SECItem *)src)->len;
if (may_stream && len == 0 && !ignoresubstream)
@ -977,6 +988,24 @@ sec_asn1e_write_contents (sec_asn1e_state *state,
}
/* otherwise, fall through to write the content */
goto process_string;
case SEC_ASN1_INTEGER:
/* ASN.1 INTEGERs are signed. PKCS#11 BigIntegers are unsigned.
* NSS will treat numbers going in and out of the ASN.1 encoder as
* unsigned, so the encoder must handle the conversion.
*/
{
SECItem *item;
item = (SECItem *)state->src;
if (item->len > 0 && item->data[0] & 0x80)
{
char zero = 0; /* write a leading 0 */
sec_asn1e_write_contents_bytes (state, &zero, 1);
}
}
/* fall through to write the content */
goto process_string;
process_string:
default: