Various fixes...
[openssl.git] / crypto / asn1 / p7_lib.c
index 2134e0974afc82d86030cfd404261ab5861cb021..76cb675497c28f6b256d60e612f94779bb81a1a6 100644 (file)
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include "asn1_mac.h"
-#include "objects.h"
+#include <openssl/asn1_mac.h>
+#include <openssl/pkcs7.h>
+#include <openssl/objects.h>
 
-/* ASN1err(ASN1_F_D2I_PKCS7,ASN1_R_BAD_PKCS7_CONTENT);
- * ASN1err(ASN1_F_I2D_PKCS7,ASN1_R_BAD_PKCS7_TYPE);
- * ASN1err(ASN1_F_PKCS7_NEW,ASN1_R_BAD_PKCS7_TYPE);
- */
+#ifdef PKCS7_INDEFINITE_ENCODING
 
-int i2d_PKCS7(a,pp)
-PKCS7 *a;
-unsigned char **pp;
+int i2d_PKCS7(PKCS7 *a, unsigned char **pp)
        {
        M_ASN1_I2D_vars(a);
 
@@ -150,10 +146,97 @@ unsigned char **pp;
        M_ASN1_I2D_finish();
        }
 
-PKCS7 *d2i_PKCS7(a,pp,length)
-PKCS7 **a;
-unsigned char **pp;
-long length;
+#else
+
+int i2d_PKCS7(PKCS7 *a, unsigned char **pp)
+       {
+       int explen = 0;
+       M_ASN1_I2D_vars(a);
+
+       if (a->asn1 != NULL)
+               {
+               if (pp == NULL)
+                       return((int)a->length);
+               memcpy(*pp,a->asn1,(int)a->length);
+               *pp+=a->length;
+               return((int)a->length);
+               }
+
+       M_ASN1_I2D_len(a->type,i2d_ASN1_OBJECT);
+       if (a->d.ptr != NULL)
+               {
+               /* Save current length */
+               r = ret;
+               switch (OBJ_obj2nid(a->type))
+                       {
+               case NID_pkcs7_data:
+                       M_ASN1_I2D_len(a->d.data,i2d_ASN1_OCTET_STRING);
+                       break;
+               case NID_pkcs7_signed:
+                       M_ASN1_I2D_len(a->d.sign,i2d_PKCS7_SIGNED);
+                       break;
+               case NID_pkcs7_enveloped:
+                       M_ASN1_I2D_len(a->d.enveloped,i2d_PKCS7_ENVELOPE);
+                       break;
+               case NID_pkcs7_signedAndEnveloped:
+                       M_ASN1_I2D_len(a->d.signed_and_enveloped,
+                               i2d_PKCS7_SIGN_ENVELOPE);
+                       break;
+               case NID_pkcs7_digest:
+                       M_ASN1_I2D_len(a->d.digest,i2d_PKCS7_DIGEST);
+                       break;
+               case NID_pkcs7_encrypted:
+                       M_ASN1_I2D_len(a->d.encrypted,i2d_PKCS7_ENCRYPT);
+                       break;
+               default:
+                       break;
+                       }
+               /* Work out explicit tag content size */
+               explen = ret - r;
+               /* Work out explicit tag size: Note: ASN1_object_size
+                * includes the content length.
+                */
+               ret =  r + ASN1_object_size(1, explen, 0);
+               }
+
+       M_ASN1_I2D_seq_total();
+
+       M_ASN1_I2D_put(a->type,i2d_ASN1_OBJECT);
+
+       if (a->d.ptr != NULL)
+               {
+               ASN1_put_object(&p, 1, explen, 0, V_ASN1_CONTEXT_SPECIFIC);
+               switch (OBJ_obj2nid(a->type))
+                       {
+               case NID_pkcs7_data:
+                       M_ASN1_I2D_put(a->d.data,i2d_ASN1_OCTET_STRING);
+                       break;
+               case NID_pkcs7_signed:
+                       M_ASN1_I2D_put(a->d.sign,i2d_PKCS7_SIGNED);
+                       break;
+               case NID_pkcs7_enveloped:
+                       M_ASN1_I2D_put(a->d.enveloped,i2d_PKCS7_ENVELOPE);
+                       break;
+               case NID_pkcs7_signedAndEnveloped:
+                       M_ASN1_I2D_put(a->d.signed_and_enveloped,
+                               i2d_PKCS7_SIGN_ENVELOPE);
+                       break;
+               case NID_pkcs7_digest:
+                       M_ASN1_I2D_put(a->d.digest,i2d_PKCS7_DIGEST);
+                       break;
+               case NID_pkcs7_encrypted:
+                       M_ASN1_I2D_put(a->d.encrypted,i2d_PKCS7_ENCRYPT);
+                       break;
+               default:
+                       break;
+                       }
+               }
+       M_ASN1_I2D_finish();
+       }
+
+#endif
+
+PKCS7 *d2i_PKCS7(PKCS7 **a, unsigned char **pp, long length)
        {
        M_ASN1_D2I_vars(a,PKCS7 *,PKCS7_new);
 
@@ -161,7 +244,7 @@ long length;
                {
                if ((*a)->asn1 != NULL)
                        {
-                       Free((char *)(*a)->asn1);
+                       OPENSSL_free((*a)->asn1);
                        (*a)->asn1=NULL;
                        }
                (*a)->length=0;
@@ -179,6 +262,7 @@ long length;
                        V_ASN1_CONTEXT_SPECIFIC|0))
                        {
                        c.error=ASN1_R_BAD_PKCS7_CONTENT;
+                       c.line=__LINE__;
                        goto err;
                        }
 
@@ -187,7 +271,7 @@ long length;
                c.q=c.p;
                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,
                        (c.inf & 1)?(length+ *pp-c.q):c.slen);
-               if (Tinf & 0x80) goto err;
+               if (Tinf & 0x80) { c.line=__LINE__; goto err; }
                c.slen-=(c.p-c.q);
 
                switch (OBJ_obj2nid(ret->type))
@@ -215,14 +299,16 @@ long length;
                        break;
                default:
                        c.error=ASN1_R_BAD_PKCS7_TYPE;
+                       c.line=__LINE__;
                        goto err;
-                       break;
+                       /* break; */
                        }
                if (Tinf == (1|V_ASN1_CONSTRUCTED))
                        {
                        if (!ASN1_check_infinite_end(&c.p,c.slen))
                                {
-                               c.error=ASN1_R_MISSING_EOS;
+                               c.error=ERR_R_MISSING_ASN1_EOS;
+                               c.line=__LINE__;
                                goto err;
                                }
                        }
@@ -233,12 +319,13 @@ long length;
        M_ASN1_D2I_Finish(a,PKCS7_free,ASN1_F_D2I_PKCS7);
        }
 
-PKCS7 *PKCS7_new()
+PKCS7 *PKCS7_new(void)
        {
        PKCS7 *ret=NULL;
+       ASN1_CTX c;
 
        M_ASN1_New_Malloc(ret,PKCS7);
-       ret->type=ASN1_OBJECT_new();
+       ret->type=OBJ_nid2obj(NID_undef);
        ret->asn1=NULL;
        ret->length=0;
        ret->detached=0;
@@ -247,8 +334,7 @@ PKCS7 *PKCS7_new()
        M_ASN1_New_Error(ASN1_F_PKCS7_NEW);
        }
 
-void PKCS7_free(a)
-PKCS7 *a;
+void PKCS7_free(PKCS7 *a)
        {
        if (a == NULL) return;
 
@@ -257,13 +343,15 @@ PKCS7 *a;
                {
                ASN1_OBJECT_free(a->type);
                }
-       Free((char *)(char *)a);
+       OPENSSL_free(a);
        }
 
-void PKCS7_content_free(a)
-PKCS7 *a;
+void PKCS7_content_free(PKCS7 *a)
        {
-       if (a->asn1 != NULL) Free((char *)a->asn1);
+       if(a == NULL)
+           return;
+
+       if (a->asn1 != NULL) OPENSSL_free(a->asn1);
 
        if (a->d.ptr != NULL)
                {
@@ -272,7 +360,7 @@ PKCS7 *a;
                switch (OBJ_obj2nid(a->type))
                        {
                case NID_pkcs7_data:
-                       ASN1_OCTET_STRING_free(a->d.data);
+                       M_ASN1_OCTET_STRING_free(a->d.data);
                        break;
                case NID_pkcs7_signed:
                        PKCS7_SIGNED_free(a->d.sign);
@@ -297,3 +385,5 @@ PKCS7 *a;
        a->d.ptr=NULL;
        }
 
+IMPLEMENT_STACK_OF(PKCS7)
+IMPLEMENT_ASN1_SET_OF(PKCS7)