X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fasn_mime.c;h=120889350ce9b11aca4720b04ccf294f356010a9;hp=c1d1b12291c4b99a9043cbf1771ef3c2b4291f22;hb=84917787b5a3df5b9077a9b8bca38f7ed65dd7b5;hpb=6d6c47980e943f3946b3894ac341d61e3c908c92 diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index c1d1b12291..120889350c 100644 --- a/crypto/asn1/asn_mime.c +++ b/crypto/asn1/asn_mime.c @@ -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 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); @@ -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; + 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; @@ -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) - return 0; + rv = 0; /* 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; } - 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")) { - 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); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -550,14 +554,30 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags) } 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) { - eol = strip_eol(linebuf, &len); + eol = strip_eol(linebuf, &len, flags); 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); - 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); @@ -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 */ - next_eol = strip_eol(linebuf, &len); + next_eol = strip_eol(linebuf, &len, 0); 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++) { - c = *p; + c = (unsigned char)*p; 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++) { - c = *p; + c = (unsigned char)*p; 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++) { - c = *p; + c = (unsigned char)*p; 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) { + 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) { + if (!(*a)->param_name || !(*b)->param_name) + return !!(*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; } -static int strip_eol(char *linebuf, int *plen) +static int strip_eol(char *linebuf, int *plen, int flags) { 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; + else if (is_eol && flags & SMIME_ASCIICRLF && c < 33) + continue; else if (c != '\r') break; }