Remove references to o_time.h
[openssl.git] / crypto / asn1 / asn_mime.c
index c1d1b12291c4b99a9043cbf1771ef3c2b4291f22..120889350ce9b11aca4720b04ccf294f356010a9 100644 (file)
@@ -102,7 +102,7 @@ static int mime_param_cmp(const MIME_PARAM * const *a,
 static void mime_param_free(MIME_PARAM *param);
 static int mime_bound_check(char *line, int linelen, char *bound, int blen);
 static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
 static void mime_param_free(MIME_PARAM *param);
 static int mime_bound_check(char *line, int linelen, char *bound, int blen);
 static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
-static int strip_eol(char *linebuf, int *plen);
+static int strip_eol(char *linebuf, int *plen, int flags);
 static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
 static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
 static void mime_hdr_free(MIME_HEADER *hdr);
 static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
 static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
 static void mime_hdr_free(MIME_HEADER *hdr);
@@ -377,8 +377,12 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
        BIO *tmpbio;
        const ASN1_AUX *aux = it->funcs;
        ASN1_STREAM_ARG sarg;
        BIO *tmpbio;
        const ASN1_AUX *aux = it->funcs;
        ASN1_STREAM_ARG sarg;
+       int rv = 1;
 
 
-       if (!(flags & SMIME_DETACHED))
+       /* If data is not deteched or resigning then the output BIO is
+        * already set up to finalise when it is written through.
+        */
+       if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST))
                {
                SMIME_crlf_copy(data, out, flags);
                return 1;
                {
                SMIME_crlf_copy(data, out, flags);
                return 1;
@@ -405,7 +409,7 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
 
        /* Finalize structure */
        if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
 
        /* Finalize structure */
        if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
-               return 0;
+               rv = 0;
 
        /* Now remove any digests prepended to the BIO */
 
 
        /* Now remove any digests prepended to the BIO */
 
@@ -416,7 +420,7 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
                sarg.ndef_bio = tmpbio;
                }
 
                sarg.ndef_bio = tmpbio;
                }
 
-       return 1;
+       return rv;
 
        }
 
 
        }
 
@@ -486,9 +490,9 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
 
                if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
                        strcmp(hdr->value, "application/pkcs7-signature")) {
 
                if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
                        strcmp(hdr->value, "application/pkcs7-signature")) {
-                       sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
                        ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
                        ERR_add_error_data(2, "type: ", hdr->value);
                        ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
                        ERR_add_error_data(2, "type: ", hdr->value);
+                       sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
                        sk_BIO_pop_free(parts, BIO_vfree);
                        return NULL;
                }
                        sk_BIO_pop_free(parts, BIO_vfree);
                        return NULL;
                }
@@ -550,14 +554,30 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
                }
        else
                {
                }
        else
                {
+               int eolcnt = 0;
                if(flags & SMIME_TEXT)
                        BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
                while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
                        {
                if(flags & SMIME_TEXT)
                        BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
                while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
                        {
-                       eol = strip_eol(linebuf, &len);
+                       eol = strip_eol(linebuf, &len, flags);
                        if (len)
                        if (len)
+                               {
+                               /* Not EOF: write out all CRLF */
+                               if (flags & SMIME_ASCIICRLF)
+                                       {
+                                       int i;
+                                       for(i = 0; i < eolcnt; i++)
+                                               BIO_write(out, "\r\n", 2);
+                                       eolcnt = 0;
+                                       }
                                BIO_write(out, linebuf, len);
                                BIO_write(out, linebuf, len);
-                       if(eol) BIO_write(out, "\r\n", 2);
+                               if(eol)
+                                       BIO_write(out, "\r\n", 2);
+                               }
+                       else if (flags & SMIME_ASCIICRLF)
+                               eolcnt++;       
+                       else if(eol)
+                               BIO_write(out, "\r\n", 2);
                        }
                }
        (void)BIO_flush(out);
                        }
                }
        (void)BIO_flush(out);
@@ -626,7 +646,7 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
                        return 1;
                } else if(part) {
                        /* Strip CR+LF from linebuf */
                        return 1;
                } else if(part) {
                        /* Strip CR+LF from linebuf */
-                       next_eol = strip_eol(linebuf, &len);
+                       next_eol = strip_eol(linebuf, &len, 0);
                        if(first) {
                                first = 0;
                                if(bpart) sk_BIO_push(parts, bpart);
                        if(first) {
                                first = 0;
                                if(bpart) sk_BIO_push(parts, bpart);
@@ -801,7 +821,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
        if(name) {
                if(!(tmpname = BUF_strdup(name))) return NULL;
                for(p = tmpname ; *p; p++) {
        if(name) {
                if(!(tmpname = BUF_strdup(name))) return NULL;
                for(p = tmpname ; *p; p++) {
-                       c = *p;
+                       c = (unsigned char)*p;
                        if(isupper(c)) {
                                c = tolower(c);
                                *p = c;
                        if(isupper(c)) {
                                c = tolower(c);
                                *p = c;
@@ -811,7 +831,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
        if(value) {
                if(!(tmpval = BUF_strdup(value))) return NULL;
                for(p = tmpval ; *p; p++) {
        if(value) {
                if(!(tmpval = BUF_strdup(value))) return NULL;
                for(p = tmpval ; *p; p++) {
-                       c = *p;
+                       c = (unsigned char)*p;
                        if(isupper(c)) {
                                c = tolower(c);
                                *p = c;
                        if(isupper(c)) {
                                c = tolower(c);
                                *p = c;
@@ -835,7 +855,7 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
                tmpname = BUF_strdup(name);
                if(!tmpname) return 0;
                for(p = tmpname ; *p; p++) {
                tmpname = BUF_strdup(name);
                if(!tmpname) return 0;
                for(p = tmpname ; *p; p++) {
-                       c = *p;
+                       c = (unsigned char)*p;
                        if(isupper(c)) {
                                c = tolower(c);
                                *p = c;
                        if(isupper(c)) {
                                c = tolower(c);
                                *p = c;
@@ -858,12 +878,17 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
 static int mime_hdr_cmp(const MIME_HEADER * const *a,
                        const MIME_HEADER * const *b)
 {
 static int mime_hdr_cmp(const MIME_HEADER * const *a,
                        const MIME_HEADER * const *b)
 {
+       if (!(*a)->name || !(*b)->name)
+               return !!(*a)->name - !!(*b)->name;
+
        return(strcmp((*a)->name, (*b)->name));
 }
 
 static int mime_param_cmp(const MIME_PARAM * const *a,
                        const MIME_PARAM * const *b)
 {
        return(strcmp((*a)->name, (*b)->name));
 }
 
 static int mime_param_cmp(const MIME_PARAM * const *a,
                        const MIME_PARAM * const *b)
 {
+       if (!(*a)->param_name || !(*b)->param_name)
+               return !!(*a)->param_name - !!(*b)->param_name;
        return(strcmp((*a)->param_name, (*b)->param_name));
 }
 
        return(strcmp((*a)->param_name, (*b)->param_name));
 }
 
@@ -923,7 +948,7 @@ static int mime_bound_check(char *line, int linelen, char *bound, int blen)
        return 0;
 }
 
        return 0;
 }
 
-static int strip_eol(char *linebuf, int *plen)
+static int strip_eol(char *linebuf, int *plen, int flags)
        {
        int len = *plen;
        char *p, c;
        {
        int len = *plen;
        char *p, c;
@@ -934,6 +959,8 @@ static int strip_eol(char *linebuf, int *plen)
                c = *p;
                if (c == '\n')
                        is_eol = 1;
                c = *p;
                if (c == '\n')
                        is_eol = 1;
+               else if (is_eol && flags & SMIME_ASCIICRLF && c < 33)
+                       continue;
                else if (c != '\r')
                        break;
                }
                else if (c != '\r')
                        break;
                }