aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/asn1/a_int.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2000-07-07 13:24:36 +0000
committerDr. Stephen Henson <steve@openssl.org>2000-07-07 13:24:36 +0000
commita338e21bd1f1654b9fc90352a45e054be1f947eb (patch)
tree3b1b06a17133076ff9331dd6a03a9d49570de31a /crypto/asn1/a_int.c
parent5789f8f780c21696c92e8138ad51afc53fa0d56d (diff)
downloadopenssl-a338e21bd1f1654b9fc90352a45e054be1f947eb.tar.gz
New ASN1 functions that just deal with
content octets, not tag+length.
Diffstat (limited to 'crypto/asn1/a_int.c')
-rw-r--r--crypto/asn1/a_int.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c
index 82db75f5e1..721592bf1c 100644
--- a/crypto/asn1/a_int.c
+++ b/crypto/asn1/a_int.c
@@ -72,8 +72,22 @@ ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x)
int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y)
{ return M_ASN1_INTEGER_cmp(x,y);}
+/* Output ASN1 INTEGER including tag+length */
+
+int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
+{
+ int len, ret;
+ len = i2c_ASN1_INTEGER(a, NULL);
+ ret=ASN1_object_size(0,len,V_ASN1_INTEGER);
+ if(pp) {
+ ASN1_put_object(pp,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL);
+ i2c_ASN1_INTEGER(a, pp);
+ }
+ return ret;
+}
+
/*
- * This converts an ASN1 INTEGER into its DER encoding.
+ * This converts an ASN1 INTEGER into its content encoding.
* The internal representation is an ASN1_STRING whose data is a big endian
* representation of the value, ignoring the sign. The sign is determined by
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
@@ -97,23 +111,23 @@ int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y)
* followed by optional zeros isn't padded.
*/
-int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
{
- int pad=0,ret,r,i,t;
+ int pad=0,ret,i,neg;
unsigned char *p,*n,pb=0;
if ((a == NULL) || (a->data == NULL)) return(0);
- t=a->type;
+ neg=a->type & V_ASN1_NEG;
if (a->length == 0)
ret=1;
else
{
ret=a->length;
i=a->data[0];
- if ((t == V_ASN1_INTEGER) && (i > 127)) {
+ if (!neg && (i > 127)) {
pad=1;
pb=0;
- } else if(t == V_ASN1_NEG_INTEGER) {
+ } else if(neg) {
if(i>128) {
pad=1;
pb=0xFF;
@@ -131,14 +145,12 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
}
ret+=pad;
}
- r=ASN1_object_size(0,ret,V_ASN1_INTEGER);
- if (pp == NULL) return(r);
+ if (pp == NULL) return(ret);
p= *pp;
- ASN1_put_object(&p,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL);
if (pad) *(p++)=pb;
if (a->length == 0) *(p++)=0;
- else if (t == V_ASN1_INTEGER) memcpy(p,a->data,(unsigned int)a->length);
+ else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
else {
/* Begin at the end of the encoding */
n=a->data + a->length - 1;
@@ -157,30 +169,22 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
}
- *pp+=r;
- return(r);
+ *pp+=ret;
+ return(ret);
}
+/* Convert DER encoded ASN1 INTEGER to ASN1_INTEGER structure */
ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp,
long length)
- {
- ASN1_INTEGER *ret=NULL;
- unsigned char *p,*to,*s, *pend;
+{
+ unsigned char *p;
long len;
- int inf,tag,xclass;
int i;
-
- if ((a == NULL) || ((*a) == NULL))
- {
- if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
- ret->type=V_ASN1_INTEGER;
- }
- else
- ret=(*a);
+ int inf,tag,xclass;
+ ASN1_INTEGER *ret;
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
- pend = p + len;
if (inf & 0x80)
{
i=ASN1_R_BAD_OBJECT_HEADER;
@@ -192,6 +196,35 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp,
i=ASN1_R_EXPECTING_AN_INTEGER;
goto err;
}
+ ret = c2i_ASN1_INTEGER(a, &p, len);
+ if(ret) *pp = p;
+ return ret;
+err:
+ ASN1err(ASN1_F_D2I_ASN1_INTEGER,i);
+ return(NULL);
+
+}
+
+
+/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
+
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp,
+ long len)
+ {
+ ASN1_INTEGER *ret=NULL;
+ unsigned char *p,*to,*s, *pend;
+ int i;
+
+ if ((a == NULL) || ((*a) == NULL))
+ {
+ if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
+ ret->type=V_ASN1_INTEGER;
+ }
+ else
+ ret=(*a);
+
+ p= *pp;
+ pend = p + len;
/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
@@ -261,6 +294,7 @@ err:
return(NULL);
}
+
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
* ASN1 integers: some broken software can encode a positive INTEGER
* with its MSB set as negative (it doesn't add a padding zero).