mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-12 00:43:38 +08:00
@@ -1,65 +1,21 @@
|
||||
/* asn_mime.c */
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
* Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "cryptlib.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/bio.h"
|
||||
#include "asn1_locl.h"
|
||||
|
||||
/*
|
||||
@@ -72,41 +28,35 @@
|
||||
* from parameter values. Quotes are stripped off
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
struct mime_param_st {
|
||||
char *param_name; /* Param name e.g. "micalg" */
|
||||
char *param_value; /* Param value e.g. "sha1" */
|
||||
} MIME_PARAM;
|
||||
};
|
||||
|
||||
DECLARE_STACK_OF(MIME_PARAM)
|
||||
IMPLEMENT_STACK_OF(MIME_PARAM)
|
||||
|
||||
typedef struct {
|
||||
struct mime_header_st {
|
||||
char *name; /* Name of line e.g. "content-type" */
|
||||
char *value; /* Value of line e.g. "text/plain" */
|
||||
STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
|
||||
} MIME_HEADER;
|
||||
|
||||
DECLARE_STACK_OF(MIME_HEADER)
|
||||
IMPLEMENT_STACK_OF(MIME_HEADER)
|
||||
};
|
||||
|
||||
static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
|
||||
const ASN1_ITEM *it);
|
||||
static char *strip_ends(char *name);
|
||||
static char *strip_start(char *name);
|
||||
static char *strip_end(char *name);
|
||||
static MIME_HEADER *mime_hdr_new(char *name, char *value);
|
||||
static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
|
||||
static MIME_HEADER *mime_hdr_new(const char *name, const char *value);
|
||||
static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value);
|
||||
static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
|
||||
static int mime_hdr_cmp(const MIME_HEADER *const *a,
|
||||
const MIME_HEADER *const *b);
|
||||
static int mime_param_cmp(const MIME_PARAM *const *a,
|
||||
const MIME_PARAM *const *b);
|
||||
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 MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
|
||||
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
|
||||
static int mime_bound_check(char *line, int linelen, const char *bound, int blen);
|
||||
static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret);
|
||||
static int strip_eol(char *linebuf, int *plen, int flags);
|
||||
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name);
|
||||
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name);
|
||||
static void mime_hdr_free(MIME_HEADER *hdr);
|
||||
|
||||
#define MAX_SMLEN 1024
|
||||
@@ -151,7 +101,7 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
|
||||
BIO *b64;
|
||||
int r;
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
if (!b64) {
|
||||
if (b64 == NULL) {
|
||||
ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
@@ -182,7 +132,8 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
|
||||
{
|
||||
BIO *b64;
|
||||
ASN1_VALUE *val;
|
||||
if (!(b64 = BIO_new(BIO_f_base64()))) {
|
||||
|
||||
if ((b64 = BIO_new(BIO_f_base64())) == NULL) {
|
||||
ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
@@ -191,7 +142,7 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
|
||||
if (!val)
|
||||
ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR);
|
||||
(void)BIO_flush(bio);
|
||||
bio = BIO_pop(bio);
|
||||
BIO_pop(bio);
|
||||
BIO_free(b64);
|
||||
return val;
|
||||
}
|
||||
@@ -246,7 +197,6 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
|
||||
case NID_id_GostR3411_94:
|
||||
BIO_puts(out, "gostr3411-94");
|
||||
goto err;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (have_unknown)
|
||||
@@ -370,7 +320,7 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
|
||||
int rv = 1;
|
||||
|
||||
/*
|
||||
* If data is not deteched or resigning then the output BIO is already
|
||||
* If data is not detached 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)) {
|
||||
@@ -430,12 +380,13 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
|
||||
if (bcont)
|
||||
*bcont = NULL;
|
||||
|
||||
if (!(headers = mime_parse_hdr(bio))) {
|
||||
if ((headers = mime_parse_hdr(bio)) == NULL) {
|
||||
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
|
||||
if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
|
||||
|| hdr->value == NULL) {
|
||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
|
||||
return NULL;
|
||||
@@ -443,7 +394,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
|
||||
|
||||
/* Handle multipart/signed */
|
||||
|
||||
if (!strcmp(hdr->value, "multipart/signed")) {
|
||||
if (strcmp(hdr->value, "multipart/signed") == 0) {
|
||||
/* Split into two parts */
|
||||
prm = mime_param_find(hdr, "boundary");
|
||||
if (!prm || !prm->param_value) {
|
||||
@@ -462,7 +413,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
|
||||
/* Parse the signature piece */
|
||||
asnin = sk_BIO_value(parts, 1);
|
||||
|
||||
if (!(headers = mime_parse_hdr(asnin))) {
|
||||
if ((headers = mime_parse_hdr(asnin)) == NULL) {
|
||||
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR);
|
||||
sk_BIO_pop_free(parts, BIO_vfree);
|
||||
return NULL;
|
||||
@@ -470,7 +421,8 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
|
||||
|
||||
/* Get content type */
|
||||
|
||||
if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
|
||||
if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
|
||||
|| hdr->value == NULL) {
|
||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
|
||||
return NULL;
|
||||
@@ -486,7 +438,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
|
||||
}
|
||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||
/* Read in ASN1 */
|
||||
if (!(val = b64_read_asn1(asnin, it))) {
|
||||
if ((val = b64_read_asn1(asnin, it)) == NULL) {
|
||||
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR);
|
||||
sk_BIO_pop_free(parts, BIO_vfree);
|
||||
return NULL;
|
||||
@@ -513,7 +465,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
|
||||
|
||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||
|
||||
if (!(val = b64_read_asn1(bio, it))) {
|
||||
if ((val = b64_read_asn1(bio, it)) == NULL) {
|
||||
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
@@ -533,20 +485,32 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
|
||||
* when streaming as we don't end up with one OCTET STRING per line.
|
||||
*/
|
||||
bf = BIO_new(BIO_f_buffer());
|
||||
if (!bf)
|
||||
if (bf == NULL)
|
||||
return 0;
|
||||
out = BIO_push(bf, out);
|
||||
if (flags & SMIME_BINARY) {
|
||||
while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
|
||||
BIO_write(out, linebuf, len);
|
||||
} 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);
|
||||
if (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)
|
||||
if (eol)
|
||||
BIO_write(out, "\r\n", 2);
|
||||
} else if (flags & SMIME_ASCIICRLF)
|
||||
eolcnt++;
|
||||
else if (eol)
|
||||
BIO_write(out, "\r\n", 2);
|
||||
}
|
||||
}
|
||||
@@ -564,11 +528,12 @@ int SMIME_text(BIO *in, BIO *out)
|
||||
STACK_OF(MIME_HEADER) *headers;
|
||||
MIME_HEADER *hdr;
|
||||
|
||||
if (!(headers = mime_parse_hdr(in))) {
|
||||
if ((headers = mime_parse_hdr(in)) == NULL) {
|
||||
ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
|
||||
if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
|
||||
|| hdr->value == NULL) {
|
||||
ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);
|
||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||
return 0;
|
||||
@@ -592,7 +557,7 @@ int SMIME_text(BIO *in, BIO *out)
|
||||
* canonical parts in a STACK of bios
|
||||
*/
|
||||
|
||||
static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
|
||||
static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret)
|
||||
{
|
||||
char linebuf[MAX_SMLEN];
|
||||
int len, blen;
|
||||
@@ -607,24 +572,32 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
|
||||
first = 1;
|
||||
parts = sk_BIO_new_null();
|
||||
*ret = parts;
|
||||
if (*ret == NULL)
|
||||
return 0;
|
||||
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
|
||||
state = mime_bound_check(linebuf, len, bound, blen);
|
||||
if (state == 1) {
|
||||
first = 1;
|
||||
part++;
|
||||
} else if (state == 2) {
|
||||
sk_BIO_push(parts, bpart);
|
||||
if (!sk_BIO_push(parts, bpart)) {
|
||||
BIO_free(bpart);
|
||||
return 0;
|
||||
}
|
||||
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 (!sk_BIO_push(parts, bpart)) {
|
||||
BIO_free(bpart);
|
||||
return 0;
|
||||
}
|
||||
bpart = BIO_new(BIO_s_mem());
|
||||
if (bpart == NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
BIO_set_mem_eof_return(bpart, 0);
|
||||
} else if (eol)
|
||||
BIO_write(bpart, "\r\n", 2);
|
||||
@@ -633,6 +606,7 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
|
||||
BIO_write(bpart, linebuf, len);
|
||||
}
|
||||
}
|
||||
BIO_free(bpart);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -651,12 +625,12 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
|
||||
char *p, *q, c;
|
||||
char *ntmp;
|
||||
char linebuf[MAX_SMLEN];
|
||||
MIME_HEADER *mhdr = NULL;
|
||||
MIME_HEADER *mhdr = NULL, *new_hdr = NULL;
|
||||
STACK_OF(MIME_HEADER) *headers;
|
||||
int len, state, save_state = 0;
|
||||
|
||||
headers = sk_MIME_HEADER_new(mime_hdr_cmp);
|
||||
if (!headers)
|
||||
if (headers == NULL)
|
||||
return NULL;
|
||||
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
|
||||
/* If whitespace at line start then continuation line */
|
||||
@@ -688,8 +662,13 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
|
||||
if (c == ';') {
|
||||
mime_debug("Found End Value\n");
|
||||
*p = 0;
|
||||
mhdr = mime_hdr_new(ntmp, strip_ends(q));
|
||||
sk_MIME_HEADER_push(headers, mhdr);
|
||||
new_hdr = mime_hdr_new(ntmp, strip_ends(q));
|
||||
if (new_hdr == NULL)
|
||||
goto err;
|
||||
if (!sk_MIME_HEADER_push(headers, new_hdr))
|
||||
goto err;
|
||||
mhdr = new_hdr;
|
||||
new_hdr = NULL;
|
||||
ntmp = NULL;
|
||||
q = p + 1;
|
||||
state = MIME_NAME;
|
||||
@@ -740,8 +719,13 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
|
||||
}
|
||||
|
||||
if (state == MIME_TYPE) {
|
||||
mhdr = mime_hdr_new(ntmp, strip_ends(q));
|
||||
sk_MIME_HEADER_push(headers, mhdr);
|
||||
new_hdr = mime_hdr_new(ntmp, strip_ends(q));
|
||||
if (new_hdr == NULL)
|
||||
goto err;
|
||||
if (!sk_MIME_HEADER_push(headers, new_hdr))
|
||||
goto err;
|
||||
mhdr = new_hdr;
|
||||
new_hdr = NULL;
|
||||
} else if (state == MIME_VALUE)
|
||||
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
|
||||
if (p == linebuf)
|
||||
@@ -750,6 +734,10 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
|
||||
|
||||
return headers;
|
||||
|
||||
err:
|
||||
mime_hdr_free(new_hdr);
|
||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *strip_ends(char *name)
|
||||
@@ -799,13 +787,14 @@ static char *strip_end(char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MIME_HEADER *mime_hdr_new(char *name, char *value)
|
||||
static MIME_HEADER *mime_hdr_new(const char *name, const char *value)
|
||||
{
|
||||
MIME_HEADER *mhdr;
|
||||
char *tmpname, *tmpval, *p;
|
||||
MIME_HEADER *mhdr = NULL;
|
||||
char *tmpname = NULL, *tmpval = NULL, *p;
|
||||
int c;
|
||||
|
||||
if (name) {
|
||||
if (!(tmpname = BUF_strdup(name)))
|
||||
if ((tmpname = OPENSSL_strdup(name)) == NULL)
|
||||
return NULL;
|
||||
for (p = tmpname; *p; p++) {
|
||||
c = (unsigned char)*p;
|
||||
@@ -814,11 +803,10 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
|
||||
*p = c;
|
||||
}
|
||||
}
|
||||
} else
|
||||
tmpname = NULL;
|
||||
}
|
||||
if (value) {
|
||||
if (!(tmpval = BUF_strdup(value)))
|
||||
return NULL;
|
||||
if ((tmpval = OPENSSL_strdup(value)) == NULL)
|
||||
goto err;
|
||||
for (p = tmpval; *p; p++) {
|
||||
c = (unsigned char)*p;
|
||||
if (isupper(c)) {
|
||||
@@ -826,27 +814,32 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
|
||||
*p = c;
|
||||
}
|
||||
}
|
||||
} else
|
||||
tmpval = NULL;
|
||||
mhdr = (MIME_HEADER *)OPENSSL_malloc(sizeof(MIME_HEADER));
|
||||
if (!mhdr)
|
||||
return NULL;
|
||||
}
|
||||
mhdr = OPENSSL_malloc(sizeof(*mhdr));
|
||||
if (mhdr == NULL)
|
||||
goto err;
|
||||
mhdr->name = tmpname;
|
||||
mhdr->value = tmpval;
|
||||
if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)))
|
||||
return NULL;
|
||||
if ((mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)) == NULL)
|
||||
goto err;
|
||||
return mhdr;
|
||||
|
||||
err:
|
||||
OPENSSL_free(tmpname);
|
||||
OPENSSL_free(tmpval);
|
||||
OPENSSL_free(mhdr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
|
||||
static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value)
|
||||
{
|
||||
char *tmpname, *tmpval, *p;
|
||||
char *tmpname = NULL, *tmpval = NULL, *p;
|
||||
int c;
|
||||
MIME_PARAM *mparam;
|
||||
MIME_PARAM *mparam = NULL;
|
||||
if (name) {
|
||||
tmpname = BUF_strdup(name);
|
||||
tmpname = OPENSSL_strdup(name);
|
||||
if (!tmpname)
|
||||
return 0;
|
||||
goto err;
|
||||
for (p = tmpname; *p; p++) {
|
||||
c = (unsigned char)*p;
|
||||
if (isupper(c)) {
|
||||
@@ -854,22 +847,26 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
|
||||
*p = c;
|
||||
}
|
||||
}
|
||||
} else
|
||||
tmpname = NULL;
|
||||
}
|
||||
if (value) {
|
||||
tmpval = BUF_strdup(value);
|
||||
tmpval = OPENSSL_strdup(value);
|
||||
if (!tmpval)
|
||||
return 0;
|
||||
} else
|
||||
tmpval = NULL;
|
||||
goto err;
|
||||
}
|
||||
/* Parameter values are case sensitive so leave as is */
|
||||
mparam = (MIME_PARAM *)OPENSSL_malloc(sizeof(MIME_PARAM));
|
||||
if (!mparam)
|
||||
return 0;
|
||||
mparam = OPENSSL_malloc(sizeof(*mparam));
|
||||
if (mparam == NULL)
|
||||
goto err;
|
||||
mparam->param_name = tmpname;
|
||||
mparam->param_value = tmpval;
|
||||
sk_MIME_PARAM_push(mhdr->params, mparam);
|
||||
if (!sk_MIME_PARAM_push(mhdr->params, mparam))
|
||||
goto err;
|
||||
return 1;
|
||||
err:
|
||||
OPENSSL_free(tmpname);
|
||||
OPENSSL_free(tmpval);
|
||||
OPENSSL_free(mparam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mime_hdr_cmp(const MIME_HEADER *const *a,
|
||||
@@ -891,22 +888,28 @@ static int mime_param_cmp(const MIME_PARAM *const *a,
|
||||
|
||||
/* Find a header with a given name (if possible) */
|
||||
|
||||
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
|
||||
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name)
|
||||
{
|
||||
MIME_HEADER htmp;
|
||||
int idx;
|
||||
htmp.name = name;
|
||||
|
||||
htmp.name = (char *)name;
|
||||
htmp.value = NULL;
|
||||
htmp.params = NULL;
|
||||
|
||||
idx = sk_MIME_HEADER_find(hdrs, &htmp);
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
return sk_MIME_HEADER_value(hdrs, idx);
|
||||
}
|
||||
|
||||
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
|
||||
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name)
|
||||
{
|
||||
MIME_PARAM param;
|
||||
int idx;
|
||||
param.param_name = name;
|
||||
|
||||
param.param_name = (char *)name;
|
||||
param.param_value = NULL;
|
||||
idx = sk_MIME_PARAM_find(hdr->params, ¶m);
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
@@ -915,10 +918,10 @@ static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
|
||||
|
||||
static void mime_hdr_free(MIME_HEADER *hdr)
|
||||
{
|
||||
if (hdr->name)
|
||||
OPENSSL_free(hdr->name);
|
||||
if (hdr->value)
|
||||
OPENSSL_free(hdr->value);
|
||||
if (hdr == NULL)
|
||||
return;
|
||||
OPENSSL_free(hdr->name);
|
||||
OPENSSL_free(hdr->value);
|
||||
if (hdr->params)
|
||||
sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
|
||||
OPENSSL_free(hdr);
|
||||
@@ -926,10 +929,8 @@ static void mime_hdr_free(MIME_HEADER *hdr)
|
||||
|
||||
static void mime_param_free(MIME_PARAM *param)
|
||||
{
|
||||
if (param->param_name)
|
||||
OPENSSL_free(param->param_name);
|
||||
if (param->param_value)
|
||||
OPENSSL_free(param->param_value);
|
||||
OPENSSL_free(param->param_name);
|
||||
OPENSSL_free(param->param_value);
|
||||
OPENSSL_free(param);
|
||||
}
|
||||
|
||||
@@ -939,7 +940,7 @@ static void mime_param_free(MIME_PARAM *param)
|
||||
* 1 : part boundary
|
||||
* 2 : final boundary
|
||||
*/
|
||||
static int mime_bound_check(char *line, int linelen, char *bound, int blen)
|
||||
static int mime_bound_check(char *line, int linelen, const char *bound, int blen)
|
||||
{
|
||||
if (linelen == -1)
|
||||
linelen = strlen(line);
|
||||
@@ -949,8 +950,9 @@ static int mime_bound_check(char *line, int linelen, char *bound, int blen)
|
||||
if (blen + 2 > linelen)
|
||||
return 0;
|
||||
/* Check for part boundary */
|
||||
if (!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
|
||||
if (!strncmp(line + blen + 2, "--", 2))
|
||||
if ((strncmp(line, "--", 2) == 0)
|
||||
&& strncmp(line + 2, bound, blen) == 0) {
|
||||
if (strncmp(line + blen + 2, "--", 2) == 0)
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
@@ -958,7 +960,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;
|
||||
@@ -968,6 +970,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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user