summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pkcs7')
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_asn1.c213
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_attr.c139
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_doit.c984
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c484
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_mime.c714
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_smime.c441
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7.h451
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7err.c160
8 files changed, 0 insertions, 3586 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_asn1.c b/src/lib/libcrypto/pkcs7/pk7_asn1.c
deleted file mode 100644
index 46f0fc9375..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_asn1.c
+++ /dev/null
@@ -1,213 +0,0 @@
1/* pk7_asn.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/asn1t.h>
62#include <openssl/pkcs7.h>
63#include <openssl/x509.h>
64
65/* PKCS#7 ASN1 module */
66
67/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
68
69ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
70
71ASN1_ADB(PKCS7) = {
72 ADB_ENTRY(NID_pkcs7_data, ASN1_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING, 0)),
73 ADB_ENTRY(NID_pkcs7_signed, ASN1_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
74 ADB_ENTRY(NID_pkcs7_enveloped, ASN1_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
75 ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
76 ADB_ENTRY(NID_pkcs7_digest, ASN1_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
77 ADB_ENTRY(NID_pkcs7_encrypted, ASN1_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
78} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
79
80ASN1_SEQUENCE(PKCS7) = {
81 ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
82 ASN1_ADB_OBJECT(PKCS7)
83}ASN1_SEQUENCE_END(PKCS7)
84
85IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
86IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
87
88ASN1_SEQUENCE(PKCS7_SIGNED) = {
89 ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
90 ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
91 ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
92 ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
93 ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
94 ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
95} ASN1_SEQUENCE_END(PKCS7_SIGNED)
96
97IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
98
99/* Minor tweak to operation: free up EVP_PKEY */
100static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
101{
102 if(operation == ASN1_OP_FREE_POST) {
103 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
104 EVP_PKEY_free(si->pkey);
105 }
106 return 1;
107}
108
109ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = {
110 ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER),
111 ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
112 ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR),
113 /* NB this should be a SET OF but we use a SEQUENCE OF so the
114 * original order * is retained when the structure is reencoded.
115 * Since the attributes are implicitly tagged this will not affect
116 * the encoding.
117 */
118 ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
119 ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR),
120 ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING),
121 ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1)
122} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO)
123
124IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
125
126ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = {
127 ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME),
128 ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER)
129} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL)
130
131IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
132
133ASN1_SEQUENCE(PKCS7_ENVELOPE) = {
134 ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
135 ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
136 ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
137} ASN1_SEQUENCE_END(PKCS7_ENVELOPE)
138
139IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
140
141/* Minor tweak to operation: free up X509 */
142static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
143{
144 if(operation == ASN1_OP_FREE_POST) {
145 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
146 X509_free(ri->cert);
147 }
148 return 1;
149}
150
151ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = {
152 ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER),
153 ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
154 ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR),
155 ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING)
156} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO)
157
158IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
159
160ASN1_SEQUENCE(PKCS7_ENC_CONTENT) = {
161 ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
162 ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
163 ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0)
164} ASN1_SEQUENCE_END(PKCS7_ENC_CONTENT)
165
166IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
167
168ASN1_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
169 ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
170 ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
171 ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
172 ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT),
173 ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
174 ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
175 ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
176} ASN1_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
177
178IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
179
180ASN1_SEQUENCE(PKCS7_ENCRYPT) = {
181 ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
182 ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
183} ASN1_SEQUENCE_END(PKCS7_ENCRYPT)
184
185IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
186
187ASN1_SEQUENCE(PKCS7_DIGEST) = {
188 ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
189 ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
190 ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
191 ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
192} ASN1_SEQUENCE_END(PKCS7_DIGEST)
193
194IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
195
196/* Specials for authenticated attributes */
197
198/* When signing attributes we want to reorder them to match the sorted
199 * encoding.
200 */
201
202ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) =
203 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
204ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN)
205
206/* When verifying attributes we need to use the received order. So
207 * we use SEQUENCE OF and tag it to SET OF
208 */
209
210ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) =
211 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
212 V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
213ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
diff --git a/src/lib/libcrypto/pkcs7/pk7_attr.c b/src/lib/libcrypto/pkcs7/pk7_attr.c
deleted file mode 100644
index 5ff5a88b5c..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_attr.c
+++ /dev/null
@@ -1,139 +0,0 @@
1/* pk7_attr.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <openssl/bio.h>
62#include <openssl/asn1.h>
63#include <openssl/pem.h>
64#include <openssl/pkcs7.h>
65#include <openssl/x509.h>
66#include <openssl/err.h>
67
68int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
69{
70 ASN1_STRING *seq;
71 unsigned char *p, *pp;
72 int len;
73 len=i2d_ASN1_SET_OF_X509_ALGOR(cap,NULL,i2d_X509_ALGOR,
74 V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL,
75 IS_SEQUENCE);
76 if(!(pp=(unsigned char *)OPENSSL_malloc(len))) {
77 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
78 return 0;
79 }
80 p=pp;
81 i2d_ASN1_SET_OF_X509_ALGOR(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
82 V_ASN1_UNIVERSAL, IS_SEQUENCE);
83 if(!(seq = ASN1_STRING_new())) {
84 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
85 return 0;
86 }
87 if(!ASN1_STRING_set (seq, pp, len)) {
88 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
89 return 0;
90 }
91 OPENSSL_free (pp);
92 return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
93 V_ASN1_SEQUENCE, seq);
94}
95
96STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
97{
98 ASN1_TYPE *cap;
99 unsigned char *p;
100 cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
101 if (!cap) return NULL;
102 p = cap->value.sequence->data;
103 return d2i_ASN1_SET_OF_X509_ALGOR(NULL, &p,
104 cap->value.sequence->length,
105 d2i_X509_ALGOR, X509_ALGOR_free,
106 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
107}
108
109/* Basic smime-capabilities OID and optional integer arg */
110int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
111{
112 X509_ALGOR *alg;
113
114 if(!(alg = X509_ALGOR_new())) {
115 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
116 return 0;
117 }
118 ASN1_OBJECT_free(alg->algorithm);
119 alg->algorithm = OBJ_nid2obj (nid);
120 if (arg > 0) {
121 ASN1_INTEGER *nbit;
122 if(!(alg->parameter = ASN1_TYPE_new())) {
123 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
124 return 0;
125 }
126 if(!(nbit = ASN1_INTEGER_new())) {
127 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
128 return 0;
129 }
130 if(!ASN1_INTEGER_set (nbit, arg)) {
131 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
132 return 0;
133 }
134 alg->parameter->value.integer = nbit;
135 alg->parameter->type = V_ASN1_INTEGER;
136 }
137 sk_X509_ALGOR_push (sk, alg);
138 return 1;
139}
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
deleted file mode 100644
index 190ca0e9bf..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ /dev/null
@@ -1,984 +0,0 @@
1/* crypto/pkcs7/pk7_doit.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/rand.h>
62#include <openssl/objects.h>
63#include <openssl/x509.h>
64#include <openssl/x509v3.h>
65
66static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
67 void *value);
68static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
69
70static int PKCS7_type_is_other(PKCS7* p7)
71 {
72 int isOther=1;
73
74 int nid=OBJ_obj2nid(p7->type);
75
76 switch( nid )
77 {
78 case NID_pkcs7_data:
79 case NID_pkcs7_signed:
80 case NID_pkcs7_enveloped:
81 case NID_pkcs7_signedAndEnveloped:
82 case NID_pkcs7_digest:
83 case NID_pkcs7_encrypted:
84 isOther=0;
85 break;
86 default:
87 isOther=1;
88 }
89
90 return isOther;
91
92 }
93
94static int PKCS7_type_is_octet_string(PKCS7* p7)
95 {
96 if ( 0==PKCS7_type_is_other(p7) )
97 return 0;
98
99 return (V_ASN1_OCTET_STRING==p7->d.other->type) ? 1 : 0;
100 }
101
102BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
103 {
104 int i,j;
105 BIO *out=NULL,*btmp=NULL;
106 X509_ALGOR *xa;
107 const EVP_MD *evp_md;
108 const EVP_CIPHER *evp_cipher=NULL;
109 STACK_OF(X509_ALGOR) *md_sk=NULL;
110 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
111 X509_ALGOR *xalg=NULL;
112 PKCS7_RECIP_INFO *ri=NULL;
113 EVP_PKEY *pkey;
114
115 i=OBJ_obj2nid(p7->type);
116 p7->state=PKCS7_S_HEADER;
117
118 switch (i)
119 {
120 case NID_pkcs7_signed:
121 md_sk=p7->d.sign->md_algs;
122 break;
123 case NID_pkcs7_signedAndEnveloped:
124 rsk=p7->d.signed_and_enveloped->recipientinfo;
125 md_sk=p7->d.signed_and_enveloped->md_algs;
126 xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
127 evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
128 if (evp_cipher == NULL)
129 {
130 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
131 PKCS7_R_CIPHER_NOT_INITIALIZED);
132 goto err;
133 }
134 break;
135 case NID_pkcs7_enveloped:
136 rsk=p7->d.enveloped->recipientinfo;
137 xalg=p7->d.enveloped->enc_data->algorithm;
138 evp_cipher=p7->d.enveloped->enc_data->cipher;
139 if (evp_cipher == NULL)
140 {
141 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
142 PKCS7_R_CIPHER_NOT_INITIALIZED);
143 goto err;
144 }
145 break;
146 default:
147 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
148 goto err;
149 }
150
151 if (md_sk != NULL)
152 {
153 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
154 {
155 xa=sk_X509_ALGOR_value(md_sk,i);
156 if ((btmp=BIO_new(BIO_f_md())) == NULL)
157 {
158 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
159 goto err;
160 }
161
162 j=OBJ_obj2nid(xa->algorithm);
163 evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
164 if (evp_md == NULL)
165 {
166 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
167 goto err;
168 }
169
170 BIO_set_md(btmp,evp_md);
171 if (out == NULL)
172 out=btmp;
173 else
174 BIO_push(out,btmp);
175 btmp=NULL;
176 }
177 }
178
179 if (evp_cipher != NULL)
180 {
181 unsigned char key[EVP_MAX_KEY_LENGTH];
182 unsigned char iv[EVP_MAX_IV_LENGTH];
183 int keylen,ivlen;
184 int jj,max;
185 unsigned char *tmp;
186 EVP_CIPHER_CTX *ctx;
187
188 if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
189 {
190 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
191 goto err;
192 }
193 BIO_get_cipher_ctx(btmp, &ctx);
194 keylen=EVP_CIPHER_key_length(evp_cipher);
195 ivlen=EVP_CIPHER_iv_length(evp_cipher);
196 if (RAND_bytes(key,keylen) <= 0)
197 goto err;
198 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
199 if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
200 EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1);
201
202 if (ivlen > 0) {
203 if (xalg->parameter == NULL)
204 xalg->parameter=ASN1_TYPE_new();
205 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
206 goto err;
207 }
208
209 /* Lets do the pub key stuff :-) */
210 max=0;
211 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
212 {
213 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
214 if (ri->cert == NULL)
215 {
216 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
217 goto err;
218 }
219 pkey=X509_get_pubkey(ri->cert);
220 jj=EVP_PKEY_size(pkey);
221 EVP_PKEY_free(pkey);
222 if (max < jj) max=jj;
223 }
224 if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
225 {
226 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
227 goto err;
228 }
229 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
230 {
231 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
232 pkey=X509_get_pubkey(ri->cert);
233 jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
234 EVP_PKEY_free(pkey);
235 if (jj <= 0)
236 {
237 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
238 OPENSSL_free(tmp);
239 goto err;
240 }
241 M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj);
242 }
243 OPENSSL_free(tmp);
244 OPENSSL_cleanse(key, keylen);
245
246 if (out == NULL)
247 out=btmp;
248 else
249 BIO_push(out,btmp);
250 btmp=NULL;
251 }
252
253 if (bio == NULL) {
254 if (PKCS7_is_detached(p7))
255 bio=BIO_new(BIO_s_null());
256 else {
257 if (PKCS7_type_is_signed(p7) ) {
258 if ( PKCS7_type_is_data(p7->d.sign->contents)) {
259 ASN1_OCTET_STRING *os;
260 os=p7->d.sign->contents->d.data;
261 if (os->length > 0)
262 bio = BIO_new_mem_buf(os->data, os->length);
263 }
264 else if ( PKCS7_type_is_octet_string(p7->d.sign->contents) ) {
265 ASN1_OCTET_STRING *os;
266 os=p7->d.sign->contents->d.other->value.octet_string;
267 if (os->length > 0)
268 bio = BIO_new_mem_buf(os->data, os->length);
269 }
270 }
271 if(bio == NULL) {
272 bio=BIO_new(BIO_s_mem());
273 BIO_set_mem_eof_return(bio,0);
274 }
275 }
276 }
277 BIO_push(out,bio);
278 bio=NULL;
279 if (0)
280 {
281err:
282 if (out != NULL)
283 BIO_free_all(out);
284 if (btmp != NULL)
285 BIO_free_all(btmp);
286 out=NULL;
287 }
288 return(out);
289 }
290
291/* int */
292BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
293 {
294 int i,j;
295 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
296 unsigned char *tmp=NULL;
297 X509_ALGOR *xa;
298 ASN1_OCTET_STRING *data_body=NULL;
299 const EVP_MD *evp_md;
300 const EVP_CIPHER *evp_cipher=NULL;
301 EVP_CIPHER_CTX *evp_ctx=NULL;
302 X509_ALGOR *enc_alg=NULL;
303 STACK_OF(X509_ALGOR) *md_sk=NULL;
304 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
305 X509_ALGOR *xalg=NULL;
306 PKCS7_RECIP_INFO *ri=NULL;
307
308 i=OBJ_obj2nid(p7->type);
309 p7->state=PKCS7_S_HEADER;
310
311 switch (i)
312 {
313 case NID_pkcs7_signed:
314 data_body=p7->d.sign->contents->d.data;
315 md_sk=p7->d.sign->md_algs;
316 break;
317 case NID_pkcs7_signedAndEnveloped:
318 rsk=p7->d.signed_and_enveloped->recipientinfo;
319 md_sk=p7->d.signed_and_enveloped->md_algs;
320 data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
321 enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
322 evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
323 if (evp_cipher == NULL)
324 {
325 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
326 goto err;
327 }
328 xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
329 break;
330 case NID_pkcs7_enveloped:
331 rsk=p7->d.enveloped->recipientinfo;
332 enc_alg=p7->d.enveloped->enc_data->algorithm;
333 data_body=p7->d.enveloped->enc_data->enc_data;
334 evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
335 if (evp_cipher == NULL)
336 {
337 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
338 goto err;
339 }
340 xalg=p7->d.enveloped->enc_data->algorithm;
341 break;
342 default:
343 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
344 goto err;
345 }
346
347 /* We will be checking the signature */
348 if (md_sk != NULL)
349 {
350 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
351 {
352 xa=sk_X509_ALGOR_value(md_sk,i);
353 if ((btmp=BIO_new(BIO_f_md())) == NULL)
354 {
355 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
356 goto err;
357 }
358
359 j=OBJ_obj2nid(xa->algorithm);
360 evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
361 if (evp_md == NULL)
362 {
363 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
364 goto err;
365 }
366
367 BIO_set_md(btmp,evp_md);
368 if (out == NULL)
369 out=btmp;
370 else
371 BIO_push(out,btmp);
372 btmp=NULL;
373 }
374 }
375
376 if (evp_cipher != NULL)
377 {
378#if 0
379 unsigned char key[EVP_MAX_KEY_LENGTH];
380 unsigned char iv[EVP_MAX_IV_LENGTH];
381 unsigned char *p;
382 int keylen,ivlen;
383 int max;
384 X509_OBJECT ret;
385#endif
386 int jj;
387
388 if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
389 {
390 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
391 goto err;
392 }
393
394 /* It was encrypted, we need to decrypt the secret key
395 * with the private key */
396
397 /* Find the recipientInfo which matches the passed certificate
398 * (if any)
399 */
400
401 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
402 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
403 if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
404 pcert->cert_info->issuer) &&
405 !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
406 ri->issuer_and_serial->serial)) break;
407 ri=NULL;
408 }
409 if (ri == NULL) {
410 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
411 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
412 goto err;
413 }
414
415 jj=EVP_PKEY_size(pkey);
416 tmp=(unsigned char *)OPENSSL_malloc(jj+10);
417 if (tmp == NULL)
418 {
419 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
420 goto err;
421 }
422
423 jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key),
424 M_ASN1_STRING_length(ri->enc_key), pkey);
425 if (jj <= 0)
426 {
427 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
428 goto err;
429 }
430
431 evp_ctx=NULL;
432 BIO_get_cipher_ctx(etmp,&evp_ctx);
433 EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0);
434 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
435 goto err;
436
437 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
438 /* Some S/MIME clients don't use the same key
439 * and effective key length. The key length is
440 * determined by the size of the decrypted RSA key.
441 */
442 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
443 {
444 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
445 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
446 goto err;
447 }
448 }
449 EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0);
450
451 OPENSSL_cleanse(tmp,jj);
452
453 if (out == NULL)
454 out=etmp;
455 else
456 BIO_push(out,etmp);
457 etmp=NULL;
458 }
459
460#if 1
461 if (PKCS7_is_detached(p7) || (in_bio != NULL))
462 {
463 bio=in_bio;
464 }
465 else
466 {
467#if 0
468 bio=BIO_new(BIO_s_mem());
469 /* We need to set this so that when we have read all
470 * the data, the encrypt BIO, if present, will read
471 * EOF and encode the last few bytes */
472 BIO_set_mem_eof_return(bio,0);
473
474 if (data_body->length > 0)
475 BIO_write(bio,(char *)data_body->data,data_body->length);
476#else
477 if (data_body->length > 0)
478 bio = BIO_new_mem_buf(data_body->data,data_body->length);
479 else {
480 bio=BIO_new(BIO_s_mem());
481 BIO_set_mem_eof_return(bio,0);
482 }
483#endif
484 }
485 BIO_push(out,bio);
486 bio=NULL;
487#endif
488 if (0)
489 {
490err:
491 if (out != NULL) BIO_free_all(out);
492 if (btmp != NULL) BIO_free_all(btmp);
493 if (etmp != NULL) BIO_free_all(etmp);
494 if (bio != NULL) BIO_free_all(bio);
495 out=NULL;
496 }
497 if (tmp != NULL)
498 OPENSSL_free(tmp);
499 return(out);
500 }
501
502int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
503 {
504 int ret=0;
505 int i,j;
506 BIO *btmp;
507 BUF_MEM *buf_mem=NULL;
508 BUF_MEM *buf=NULL;
509 PKCS7_SIGNER_INFO *si;
510 EVP_MD_CTX *mdc,ctx_tmp;
511 STACK_OF(X509_ATTRIBUTE) *sk;
512 STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
513 ASN1_OCTET_STRING *os=NULL;
514
515 EVP_MD_CTX_init(&ctx_tmp);
516 i=OBJ_obj2nid(p7->type);
517 p7->state=PKCS7_S_HEADER;
518
519 switch (i)
520 {
521 case NID_pkcs7_signedAndEnveloped:
522 /* XXXXXXXXXXXXXXXX */
523 si_sk=p7->d.signed_and_enveloped->signer_info;
524 os=M_ASN1_OCTET_STRING_new();
525 p7->d.signed_and_enveloped->enc_data->enc_data=os;
526 break;
527 case NID_pkcs7_enveloped:
528 /* XXXXXXXXXXXXXXXX */
529 os=M_ASN1_OCTET_STRING_new();
530 p7->d.enveloped->enc_data->enc_data=os;
531 break;
532 case NID_pkcs7_signed:
533 si_sk=p7->d.sign->signer_info;
534 os=p7->d.sign->contents->d.data;
535 /* If detached data then the content is excluded */
536 if(p7->detached) {
537 M_ASN1_OCTET_STRING_free(os);
538 p7->d.sign->contents->d.data = NULL;
539 }
540 break;
541 }
542
543 if (si_sk != NULL)
544 {
545 if ((buf=BUF_MEM_new()) == NULL)
546 {
547 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
548 goto err;
549 }
550 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
551 {
552 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
553 if (si->pkey == NULL) continue;
554
555 j=OBJ_obj2nid(si->digest_alg->algorithm);
556
557 btmp=bio;
558 for (;;)
559 {
560 if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD))
561 == NULL)
562 {
563 PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
564 goto err;
565 }
566 BIO_get_md_ctx(btmp,&mdc);
567 if (mdc == NULL)
568 {
569 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR);
570 goto err;
571 }
572 if (EVP_MD_CTX_type(mdc) == j)
573 break;
574 else
575 btmp=BIO_next(btmp);
576 }
577
578 /* We now have the EVP_MD_CTX, lets do the
579 * signing. */
580 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
581 if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
582 {
583 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
584 goto err;
585 }
586
587 sk=si->auth_attr;
588
589 /* If there are attributes, we add the digest
590 * attribute and only sign the attributes */
591 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
592 {
593 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
594 unsigned int md_len, alen;
595 ASN1_OCTET_STRING *digest;
596 ASN1_UTCTIME *sign_time;
597 const EVP_MD *md_tmp;
598
599 /* Add signing time if not already present */
600 if (!PKCS7_get_signed_attribute(si,
601 NID_pkcs9_signingTime))
602 {
603 sign_time=X509_gmtime_adj(NULL,0);
604 PKCS7_add_signed_attribute(si,
605 NID_pkcs9_signingTime,
606 V_ASN1_UTCTIME,sign_time);
607 }
608
609 /* Add digest */
610 md_tmp=EVP_MD_CTX_md(&ctx_tmp);
611 EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
612 digest=M_ASN1_OCTET_STRING_new();
613 M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
614 PKCS7_add_signed_attribute(si,
615 NID_pkcs9_messageDigest,
616 V_ASN1_OCTET_STRING,digest);
617
618 /* Now sign the attributes */
619 EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
620 alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
621 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
622 if(!abuf) goto err;
623 EVP_SignUpdate(&ctx_tmp,abuf,alen);
624 OPENSSL_free(abuf);
625 }
626
627#ifndef OPENSSL_NO_DSA
628 if (si->pkey->type == EVP_PKEY_DSA)
629 ctx_tmp.digest=EVP_dss1();
630#endif
631
632 if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
633 (unsigned int *)&buf->length,si->pkey))
634 {
635 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB);
636 goto err;
637 }
638 if (!ASN1_STRING_set(si->enc_digest,
639 (unsigned char *)buf->data,buf->length))
640 {
641 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB);
642 goto err;
643 }
644 }
645 }
646
647 if (!PKCS7_is_detached(p7))
648 {
649 btmp=BIO_find_type(bio,BIO_TYPE_MEM);
650 if (btmp == NULL)
651 {
652 PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
653 goto err;
654 }
655 BIO_get_mem_ptr(btmp,&buf_mem);
656 /* Mark the BIO read only then we can use its copy of the data
657 * instead of making an extra copy.
658 */
659 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
660 BIO_set_mem_eof_return(btmp, 0);
661 os->data = (unsigned char *)buf_mem->data;
662 os->length = buf_mem->length;
663#if 0
664 M_ASN1_OCTET_STRING_set(os,
665 (unsigned char *)buf_mem->data,buf_mem->length);
666#endif
667 }
668 ret=1;
669err:
670 EVP_MD_CTX_cleanup(&ctx_tmp);
671 if (buf != NULL) BUF_MEM_free(buf);
672 return(ret);
673 }
674
675int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
676 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
677 {
678 PKCS7_ISSUER_AND_SERIAL *ias;
679 int ret=0,i;
680 STACK_OF(X509) *cert;
681 X509 *x509;
682
683 if (PKCS7_type_is_signed(p7))
684 {
685 cert=p7->d.sign->cert;
686 }
687 else if (PKCS7_type_is_signedAndEnveloped(p7))
688 {
689 cert=p7->d.signed_and_enveloped->cert;
690 }
691 else
692 {
693 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);
694 goto err;
695 }
696 /* XXXXXXXXXXXXXXXXXXXXXXX */
697 ias=si->issuer_and_serial;
698
699 x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);
700
701 /* were we able to find the cert in passed to us */
702 if (x509 == NULL)
703 {
704 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
705 goto err;
706 }
707
708 /* Lets verify */
709 if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
710 {
711 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
712 goto err;
713 }
714 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
715 i=X509_verify_cert(ctx);
716 if (i <= 0)
717 {
718 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
719 X509_STORE_CTX_cleanup(ctx);
720 goto err;
721 }
722 X509_STORE_CTX_cleanup(ctx);
723
724 return PKCS7_signatureVerify(bio, p7, si, x509);
725 err:
726 return ret;
727 }
728
729int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
730 X509 *x509)
731 {
732 ASN1_OCTET_STRING *os;
733 EVP_MD_CTX mdc_tmp,*mdc;
734 int ret=0,i;
735 int md_type;
736 STACK_OF(X509_ATTRIBUTE) *sk;
737 BIO *btmp;
738 EVP_PKEY *pkey;
739
740 EVP_MD_CTX_init(&mdc_tmp);
741
742 if (!PKCS7_type_is_signed(p7) &&
743 !PKCS7_type_is_signedAndEnveloped(p7)) {
744 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
745 PKCS7_R_WRONG_PKCS7_TYPE);
746 goto err;
747 }
748
749 md_type=OBJ_obj2nid(si->digest_alg->algorithm);
750
751 btmp=bio;
752 for (;;)
753 {
754 if ((btmp == NULL) ||
755 ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
756 {
757 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
758 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
759 goto err;
760 }
761 BIO_get_md_ctx(btmp,&mdc);
762 if (mdc == NULL)
763 {
764 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
765 ERR_R_INTERNAL_ERROR);
766 goto err;
767 }
768 if (EVP_MD_CTX_type(mdc) == md_type)
769 break;
770 /* Workaround for some broken clients that put the signature
771 * OID instead of the digest OID in digest_alg->algorithm
772 */
773 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
774 break;
775 btmp=BIO_next(btmp);
776 }
777
778 /* mdc is the digest ctx that we want, unless there are attributes,
779 * in which case the digest is the signed attributes */
780 EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);
781
782 sk=si->auth_attr;
783 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
784 {
785 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
786 unsigned int md_len, alen;
787 ASN1_OCTET_STRING *message_digest;
788
789 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
790 message_digest=PKCS7_digest_from_attributes(sk);
791 if (!message_digest)
792 {
793 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
794 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
795 goto err;
796 }
797 if ((message_digest->length != (int)md_len) ||
798 (memcmp(message_digest->data,md_dat,md_len)))
799 {
800#if 0
801{
802int ii;
803for (ii=0; ii<message_digest->length; ii++)
804 printf("%02X",message_digest->data[ii]); printf(" sent\n");
805for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
806}
807#endif
808 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
809 PKCS7_R_DIGEST_FAILURE);
810 ret= -1;
811 goto err;
812 }
813
814 EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);
815
816 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
817 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
818 EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
819
820 OPENSSL_free(abuf);
821 }
822
823 os=si->enc_digest;
824 pkey = X509_get_pubkey(x509);
825 if (!pkey)
826 {
827 ret = -1;
828 goto err;
829 }
830#ifndef OPENSSL_NO_DSA
831 if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
832#endif
833
834 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
835 EVP_PKEY_free(pkey);
836 if (i <= 0)
837 {
838 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
839 PKCS7_R_SIGNATURE_FAILURE);
840 ret= -1;
841 goto err;
842 }
843 else
844 ret=1;
845err:
846 EVP_MD_CTX_cleanup(&mdc_tmp);
847 return(ret);
848 }
849
850PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
851 {
852 STACK_OF(PKCS7_RECIP_INFO) *rsk;
853 PKCS7_RECIP_INFO *ri;
854 int i;
855
856 i=OBJ_obj2nid(p7->type);
857 if (i != NID_pkcs7_signedAndEnveloped) return(NULL);
858 rsk=p7->d.signed_and_enveloped->recipientinfo;
859 ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
860 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
861 ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
862 return(ri->issuer_and_serial);
863 }
864
865ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
866 {
867 return(get_attribute(si->auth_attr,nid));
868 }
869
870ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
871 {
872 return(get_attribute(si->unauth_attr,nid));
873 }
874
875static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
876 {
877 int i;
878 X509_ATTRIBUTE *xa;
879 ASN1_OBJECT *o;
880
881 o=OBJ_nid2obj(nid);
882 if (!o || !sk) return(NULL);
883 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
884 {
885 xa=sk_X509_ATTRIBUTE_value(sk,i);
886 if (OBJ_cmp(xa->object,o) == 0)
887 {
888 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
889 return(sk_ASN1_TYPE_value(xa->value.set,0));
890 else
891 return(NULL);
892 }
893 }
894 return(NULL);
895 }
896
897ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
898{
899 ASN1_TYPE *astype;
900 if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
901 return astype->value.octet_string;
902}
903
904int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
905 STACK_OF(X509_ATTRIBUTE) *sk)
906 {
907 int i;
908
909 if (p7si->auth_attr != NULL)
910 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
911 p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
912 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
913 {
914 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
915 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
916 == NULL)
917 return(0);
918 }
919 return(1);
920 }
921
922int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
923 {
924 int i;
925
926 if (p7si->unauth_attr != NULL)
927 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
928 X509_ATTRIBUTE_free);
929 p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
930 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
931 {
932 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
933 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
934 == NULL)
935 return(0);
936 }
937 return(1);
938 }
939
940int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
941 void *value)
942 {
943 return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
944 }
945
946int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
947 void *value)
948 {
949 return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
950 }
951
952static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
953 void *value)
954 {
955 X509_ATTRIBUTE *attr=NULL;
956
957 if (*sk == NULL)
958 {
959 *sk = sk_X509_ATTRIBUTE_new_null();
960new_attrib:
961 attr=X509_ATTRIBUTE_create(nid,atrtype,value);
962 sk_X509_ATTRIBUTE_push(*sk,attr);
963 }
964 else
965 {
966 int i;
967
968 for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++)
969 {
970 attr=sk_X509_ATTRIBUTE_value(*sk,i);
971 if (OBJ_obj2nid(attr->object) == nid)
972 {
973 X509_ATTRIBUTE_free(attr);
974 attr=X509_ATTRIBUTE_create(nid,atrtype,value);
975 sk_X509_ATTRIBUTE_set(*sk,i,attr);
976 goto end;
977 }
978 }
979 goto new_attrib;
980 }
981end:
982 return(1);
983 }
984
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
deleted file mode 100644
index 985b07245c..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ /dev/null
@@ -1,484 +0,0 @@
1/* crypto/pkcs7/pk7_lib.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/x509.h>
63
64long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
65 {
66 int nid;
67 long ret;
68
69 nid=OBJ_obj2nid(p7->type);
70
71 switch (cmd)
72 {
73 case PKCS7_OP_SET_DETACHED_SIGNATURE:
74 if (nid == NID_pkcs7_signed)
75 {
76 ret=p7->detached=(int)larg;
77 if (ret && PKCS7_type_is_data(p7->d.sign->contents))
78 {
79 ASN1_OCTET_STRING *os;
80 os=p7->d.sign->contents->d.data;
81 ASN1_OCTET_STRING_free(os);
82 p7->d.sign->contents->d.data = NULL;
83 }
84 }
85 else
86 {
87 PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
88 ret=0;
89 }
90 break;
91 case PKCS7_OP_GET_DETACHED_SIGNATURE:
92 if (nid == NID_pkcs7_signed)
93 {
94 if(!p7->d.sign || !p7->d.sign->contents->d.ptr)
95 ret = 1;
96 else ret = 0;
97
98 p7->detached = ret;
99 }
100 else
101 {
102 PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
103 ret=0;
104 }
105
106 break;
107 default:
108 PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION);
109 ret=0;
110 }
111 return(ret);
112 }
113
114int PKCS7_content_new(PKCS7 *p7, int type)
115 {
116 PKCS7 *ret=NULL;
117
118 if ((ret=PKCS7_new()) == NULL) goto err;
119 if (!PKCS7_set_type(ret,type)) goto err;
120 if (!PKCS7_set_content(p7,ret)) goto err;
121
122 return(1);
123err:
124 if (ret != NULL) PKCS7_free(ret);
125 return(0);
126 }
127
128int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
129 {
130 int i;
131
132 i=OBJ_obj2nid(p7->type);
133 switch (i)
134 {
135 case NID_pkcs7_signed:
136 if (p7->d.sign->contents != NULL)
137 PKCS7_free(p7->d.sign->contents);
138 p7->d.sign->contents=p7_data;
139 break;
140 case NID_pkcs7_digest:
141 case NID_pkcs7_data:
142 case NID_pkcs7_enveloped:
143 case NID_pkcs7_signedAndEnveloped:
144 case NID_pkcs7_encrypted:
145 default:
146 PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
147 goto err;
148 }
149 return(1);
150err:
151 return(0);
152 }
153
154int PKCS7_set_type(PKCS7 *p7, int type)
155 {
156 ASN1_OBJECT *obj;
157
158 /*PKCS7_content_free(p7);*/
159 obj=OBJ_nid2obj(type); /* will not fail */
160
161 switch (type)
162 {
163 case NID_pkcs7_signed:
164 p7->type=obj;
165 if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
166 goto err;
167 ASN1_INTEGER_set(p7->d.sign->version,1);
168 break;
169 case NID_pkcs7_data:
170 p7->type=obj;
171 if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
172 goto err;
173 break;
174 case NID_pkcs7_signedAndEnveloped:
175 p7->type=obj;
176 if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
177 == NULL) goto err;
178 ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
179 p7->d.signed_and_enveloped->enc_data->content_type
180 = OBJ_nid2obj(NID_pkcs7_data);
181 break;
182 case NID_pkcs7_enveloped:
183 p7->type=obj;
184 if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
185 == NULL) goto err;
186 ASN1_INTEGER_set(p7->d.enveloped->version,0);
187 p7->d.enveloped->enc_data->content_type
188 = OBJ_nid2obj(NID_pkcs7_data);
189 break;
190 case NID_pkcs7_encrypted:
191 p7->type=obj;
192 if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
193 == NULL) goto err;
194 ASN1_INTEGER_set(p7->d.encrypted->version,0);
195 p7->d.encrypted->enc_data->content_type
196 = OBJ_nid2obj(NID_pkcs7_data);
197 break;
198
199 case NID_pkcs7_digest:
200 default:
201 PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
202 goto err;
203 }
204 return(1);
205err:
206 return(0);
207 }
208
209int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
210 {
211 int i,j,nid;
212 X509_ALGOR *alg;
213 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
214 STACK_OF(X509_ALGOR) *md_sk;
215
216 i=OBJ_obj2nid(p7->type);
217 switch (i)
218 {
219 case NID_pkcs7_signed:
220 signer_sk= p7->d.sign->signer_info;
221 md_sk= p7->d.sign->md_algs;
222 break;
223 case NID_pkcs7_signedAndEnveloped:
224 signer_sk= p7->d.signed_and_enveloped->signer_info;
225 md_sk= p7->d.signed_and_enveloped->md_algs;
226 break;
227 default:
228 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
229 return(0);
230 }
231
232 nid=OBJ_obj2nid(psi->digest_alg->algorithm);
233
234 /* If the digest is not currently listed, add it */
235 j=0;
236 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
237 {
238 alg=sk_X509_ALGOR_value(md_sk,i);
239 if (OBJ_obj2nid(alg->algorithm) == nid)
240 {
241 j=1;
242 break;
243 }
244 }
245 if (!j) /* we need to add another algorithm */
246 {
247 if(!(alg=X509_ALGOR_new())
248 || !(alg->parameter = ASN1_TYPE_new())) {
249 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
250 return(0);
251 }
252 alg->algorithm=OBJ_nid2obj(nid);
253 alg->parameter->type = V_ASN1_NULL;
254 sk_X509_ALGOR_push(md_sk,alg);
255 }
256
257 sk_PKCS7_SIGNER_INFO_push(signer_sk,psi);
258 return(1);
259 }
260
261int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
262 {
263 int i;
264 STACK_OF(X509) **sk;
265
266 i=OBJ_obj2nid(p7->type);
267 switch (i)
268 {
269 case NID_pkcs7_signed:
270 sk= &(p7->d.sign->cert);
271 break;
272 case NID_pkcs7_signedAndEnveloped:
273 sk= &(p7->d.signed_and_enveloped->cert);
274 break;
275 default:
276 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE);
277 return(0);
278 }
279
280 if (*sk == NULL)
281 *sk=sk_X509_new_null();
282 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
283 sk_X509_push(*sk,x509);
284 return(1);
285 }
286
287int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
288 {
289 int i;
290 STACK_OF(X509_CRL) **sk;
291
292 i=OBJ_obj2nid(p7->type);
293 switch (i)
294 {
295 case NID_pkcs7_signed:
296 sk= &(p7->d.sign->crl);
297 break;
298 case NID_pkcs7_signedAndEnveloped:
299 sk= &(p7->d.signed_and_enveloped->crl);
300 break;
301 default:
302 PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE);
303 return(0);
304 }
305
306 if (*sk == NULL)
307 *sk=sk_X509_CRL_new_null();
308
309 CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
310 sk_X509_CRL_push(*sk,crl);
311 return(1);
312 }
313
314int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
315 const EVP_MD *dgst)
316 {
317 char is_dsa;
318 if (pkey->type == EVP_PKEY_DSA) is_dsa = 1;
319 else is_dsa = 0;
320 /* We now need to add another PKCS7_SIGNER_INFO entry */
321 ASN1_INTEGER_set(p7i->version,1);
322 X509_NAME_set(&p7i->issuer_and_serial->issuer,
323 X509_get_issuer_name(x509));
324
325 /* because ASN1_INTEGER_set is used to set a 'long' we will do
326 * things the ugly way. */
327 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
328 p7i->issuer_and_serial->serial=
329 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509));
330
331 /* lets keep the pkey around for a while */
332 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
333 p7i->pkey=pkey;
334
335 /* Set the algorithms */
336 if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
337 else
338 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
339
340 if (p7i->digest_alg->parameter != NULL)
341 ASN1_TYPE_free(p7i->digest_alg->parameter);
342 if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
343 goto err;
344 p7i->digest_alg->parameter->type=V_ASN1_NULL;
345
346 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(EVP_PKEY_type(pkey->type));
347
348 if (p7i->digest_enc_alg->parameter != NULL)
349 ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
350 if(is_dsa) p7i->digest_enc_alg->parameter = NULL;
351 else {
352 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
353 goto err;
354 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
355 }
356
357 return(1);
358err:
359 return(0);
360 }
361
362PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
363 const EVP_MD *dgst)
364 {
365 PKCS7_SIGNER_INFO *si;
366
367 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
368 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
369 if (!PKCS7_add_signer(p7,si)) goto err;
370 return(si);
371err:
372 return(NULL);
373 }
374
375STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
376 {
377 if (PKCS7_type_is_signed(p7))
378 {
379 return(p7->d.sign->signer_info);
380 }
381 else if (PKCS7_type_is_signedAndEnveloped(p7))
382 {
383 return(p7->d.signed_and_enveloped->signer_info);
384 }
385 else
386 return(NULL);
387 }
388
389PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
390 {
391 PKCS7_RECIP_INFO *ri;
392
393 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
394 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
395 if (!PKCS7_add_recipient_info(p7,ri)) goto err;
396 return(ri);
397err:
398 return(NULL);
399 }
400
401int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
402 {
403 int i;
404 STACK_OF(PKCS7_RECIP_INFO) *sk;
405
406 i=OBJ_obj2nid(p7->type);
407 switch (i)
408 {
409 case NID_pkcs7_signedAndEnveloped:
410 sk= p7->d.signed_and_enveloped->recipientinfo;
411 break;
412 case NID_pkcs7_enveloped:
413 sk= p7->d.enveloped->recipientinfo;
414 break;
415 default:
416 PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE);
417 return(0);
418 }
419
420 sk_PKCS7_RECIP_INFO_push(sk,ri);
421 return(1);
422 }
423
424int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
425 {
426 ASN1_INTEGER_set(p7i->version,0);
427 X509_NAME_set(&p7i->issuer_and_serial->issuer,
428 X509_get_issuer_name(x509));
429
430 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
431 p7i->issuer_and_serial->serial=
432 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509));
433
434 X509_ALGOR_free(p7i->key_enc_algor);
435 p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor);
436
437 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
438 p7i->cert=x509;
439
440 return(1);
441 }
442
443X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
444 {
445 if (PKCS7_type_is_signed(p7))
446 return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
447 si->issuer_and_serial->issuer,
448 si->issuer_and_serial->serial));
449 else
450 return(NULL);
451 }
452
453int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
454 {
455 int i;
456 ASN1_OBJECT *objtmp;
457 PKCS7_ENC_CONTENT *ec;
458
459 i=OBJ_obj2nid(p7->type);
460 switch (i)
461 {
462 case NID_pkcs7_signedAndEnveloped:
463 ec=p7->d.signed_and_enveloped->enc_data;
464 break;
465 case NID_pkcs7_enveloped:
466 ec=p7->d.enveloped->enc_data;
467 break;
468 default:
469 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE);
470 return(0);
471 }
472
473 /* Check cipher OID exists and has data in it*/
474 i = EVP_CIPHER_type(cipher);
475 if(i == NID_undef) {
476 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
477 return(0);
478 }
479 objtmp = OBJ_nid2obj(i);
480
481 ec->cipher = cipher;
482 return 1;
483 }
484
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c
deleted file mode 100644
index 5d2a97839d..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_mime.c
+++ /dev/null
@@ -1,714 +0,0 @@
1/* pk7_mime.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <ctype.h>
61#include "cryptlib.h"
62#include <openssl/rand.h>
63#include <openssl/x509.h>
64
65/* MIME and related routines */
66
67/* MIME format structures
68 * Note that all are translated to lower case apart from
69 * parameter values. Quotes are stripped off
70 */
71
72typedef struct {
73char *param_name; /* Param name e.g. "micalg" */
74char *param_value; /* Param value e.g. "sha1" */
75} MIME_PARAM;
76
77DECLARE_STACK_OF(MIME_PARAM)
78IMPLEMENT_STACK_OF(MIME_PARAM)
79
80typedef struct {
81char *name; /* Name of line e.g. "content-type" */
82char *value; /* Value of line e.g. "text/plain" */
83STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
84} MIME_HEADER;
85
86DECLARE_STACK_OF(MIME_HEADER)
87IMPLEMENT_STACK_OF(MIME_HEADER)
88
89static int B64_write_PKCS7(BIO *bio, PKCS7 *p7);
90static PKCS7 *B64_read_PKCS7(BIO *bio);
91static char * strip_ends(char *name);
92static char * strip_start(char *name);
93static char * strip_end(char *name);
94static MIME_HEADER *mime_hdr_new(char *name, char *value);
95static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
96static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
97static int mime_hdr_cmp(const MIME_HEADER * const *a,
98 const MIME_HEADER * const *b);
99static int mime_param_cmp(const MIME_PARAM * const *a,
100 const MIME_PARAM * const *b);
101static void mime_param_free(MIME_PARAM *param);
102static int mime_bound_check(char *line, int linelen, char *bound, int blen);
103static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
104static int strip_eol(char *linebuf, int *plen);
105static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
106static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
107static void mime_hdr_free(MIME_HEADER *hdr);
108
109#define MAX_SMLEN 1024
110#define mime_debug(x) /* x */
111
112
113typedef void (*stkfree)();
114
115/* Base 64 read and write of PKCS#7 structure */
116
117static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
118{
119 BIO *b64;
120 if(!(b64 = BIO_new(BIO_f_base64()))) {
121 PKCS7err(PKCS7_F_B64_WRITE_PKCS7,ERR_R_MALLOC_FAILURE);
122 return 0;
123 }
124 bio = BIO_push(b64, bio);
125 i2d_PKCS7_bio(bio, p7);
126 BIO_flush(bio);
127 bio = BIO_pop(bio);
128 BIO_free(b64);
129 return 1;
130}
131
132static PKCS7 *B64_read_PKCS7(BIO *bio)
133{
134 BIO *b64;
135 PKCS7 *p7;
136 if(!(b64 = BIO_new(BIO_f_base64()))) {
137 PKCS7err(PKCS7_F_B64_READ_PKCS7,ERR_R_MALLOC_FAILURE);
138 return 0;
139 }
140 bio = BIO_push(b64, bio);
141 if(!(p7 = d2i_PKCS7_bio(bio, NULL)))
142 PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR);
143 BIO_flush(bio);
144 bio = BIO_pop(bio);
145 BIO_free(b64);
146 return p7;
147}
148
149/* SMIME sender */
150
151int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
152{
153 char bound[33], c;
154 int i;
155 char *mime_prefix, *mime_eol;
156 if (flags & PKCS7_NOOLDMIMETYPE)
157 mime_prefix = "application/pkcs7-";
158 else
159 mime_prefix = "application/x-pkcs7-";
160 if (flags & PKCS7_CRLFEOL)
161 mime_eol = "\r\n";
162 else
163 mime_eol = "\n";
164 if((flags & PKCS7_DETACHED) && data) {
165 /* We want multipart/signed */
166 /* Generate a random boundary */
167 RAND_pseudo_bytes((unsigned char *)bound, 32);
168 for(i = 0; i < 32; i++) {
169 c = bound[i] & 0xf;
170 if(c < 10) c += '0';
171 else c += 'A' - 10;
172 bound[i] = c;
173 }
174 bound[32] = 0;
175 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
176 BIO_printf(bio, "Content-Type: multipart/signed;");
177 BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
178 BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"%s%s",
179 bound, mime_eol, mime_eol);
180 BIO_printf(bio, "This is an S/MIME signed message%s%s",
181 mime_eol, mime_eol);
182 /* Now write out the first part */
183 BIO_printf(bio, "------%s%s", bound, mime_eol);
184 SMIME_crlf_copy(data, bio, flags);
185 BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
186
187 /* Headers for signature */
188
189 BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
190 BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
191 BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
192 mime_eol);
193 BIO_printf(bio, "Content-Disposition: attachment;");
194 BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
195 mime_eol, mime_eol);
196 B64_write_PKCS7(bio, p7);
197 BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
198 mime_eol, mime_eol);
199 return 1;
200 }
201 /* MIME headers */
202 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
203 BIO_printf(bio, "Content-Disposition: attachment;");
204 BIO_printf(bio, " filename=\"smime.p7m\"%s", mime_eol);
205 BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
206 BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol);
207 BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
208 mime_eol, mime_eol);
209 B64_write_PKCS7(bio, p7);
210 BIO_printf(bio, "%s", mime_eol);
211 return 1;
212}
213
214/* SMIME reader: handle multipart/signed and opaque signing.
215 * in multipart case the content is placed in a memory BIO
216 * pointed to by "bcont". In opaque this is set to NULL
217 */
218
219PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
220{
221 BIO *p7in;
222 STACK_OF(MIME_HEADER) *headers = NULL;
223 STACK_OF(BIO) *parts = NULL;
224 MIME_HEADER *hdr;
225 MIME_PARAM *prm;
226 PKCS7 *p7;
227 int ret;
228
229 if(bcont) *bcont = NULL;
230
231 if (!(headers = mime_parse_hdr(bio))) {
232 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_PARSE_ERROR);
233 return NULL;
234 }
235
236 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
237 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
238 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_CONTENT_TYPE);
239 return NULL;
240 }
241
242 /* Handle multipart/signed */
243
244 if(!strcmp(hdr->value, "multipart/signed")) {
245 /* Split into two parts */
246 prm = mime_param_find(hdr, "boundary");
247 if(!prm || !prm->param_value) {
248 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
249 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BOUNDARY);
250 return NULL;
251 }
252 ret = multi_split(bio, prm->param_value, &parts);
253 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
254 if(!ret || (sk_BIO_num(parts) != 2) ) {
255 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BODY_FAILURE);
256 sk_BIO_pop_free(parts, BIO_vfree);
257 return NULL;
258 }
259
260 /* Parse the signature piece */
261 p7in = sk_BIO_value(parts, 1);
262
263 if (!(headers = mime_parse_hdr(p7in))) {
264 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_SIG_PARSE_ERROR);
265 sk_BIO_pop_free(parts, BIO_vfree);
266 return NULL;
267 }
268
269 /* Get content type */
270
271 if(!(hdr = mime_hdr_find(headers, "content-type")) ||
272 !hdr->value) {
273 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
274 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_SIG_CONTENT_TYPE);
275 return NULL;
276 }
277
278 if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
279 strcmp(hdr->value, "application/pkcs7-signature")) {
280 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
281 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_SIG_INVALID_MIME_TYPE);
282 ERR_add_error_data(2, "type: ", hdr->value);
283 sk_BIO_pop_free(parts, BIO_vfree);
284 return NULL;
285 }
286 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
287 /* Read in PKCS#7 */
288 if(!(p7 = B64_read_PKCS7(p7in))) {
289 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_PKCS7_SIG_PARSE_ERROR);
290 sk_BIO_pop_free(parts, BIO_vfree);
291 return NULL;
292 }
293
294 if(bcont) {
295 *bcont = sk_BIO_value(parts, 0);
296 BIO_free(p7in);
297 sk_BIO_free(parts);
298 } else sk_BIO_pop_free(parts, BIO_vfree);
299 return p7;
300 }
301
302 /* OK, if not multipart/signed try opaque signature */
303
304 if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
305 strcmp (hdr->value, "application/pkcs7-mime")) {
306 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_INVALID_MIME_TYPE);
307 ERR_add_error_data(2, "type: ", hdr->value);
308 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
309 return NULL;
310 }
311
312 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
313
314 if(!(p7 = B64_read_PKCS7(bio))) {
315 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_PKCS7_PARSE_ERROR);
316 return NULL;
317 }
318 return p7;
319
320}
321
322/* Copy text from one BIO to another making the output CRLF at EOL */
323int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
324{
325 char eol;
326 int len;
327 char linebuf[MAX_SMLEN];
328 if(flags & PKCS7_BINARY) {
329 while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
330 BIO_write(out, linebuf, len);
331 return 1;
332 }
333 if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
334 while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
335 eol = strip_eol(linebuf, &len);
336 if (len)
337 BIO_write(out, linebuf, len);
338 if(eol) BIO_write(out, "\r\n", 2);
339 }
340 return 1;
341}
342
343/* Strip off headers if they are text/plain */
344int SMIME_text(BIO *in, BIO *out)
345{
346 char iobuf[4096];
347 int len;
348 STACK_OF(MIME_HEADER) *headers;
349 MIME_HEADER *hdr;
350
351 if (!(headers = mime_parse_hdr(in))) {
352 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR);
353 return 0;
354 }
355 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
356 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE);
357 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
358 return 0;
359 }
360 if (strcmp (hdr->value, "text/plain")) {
361 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE);
362 ERR_add_error_data(2, "type: ", hdr->value);
363 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
364 return 0;
365 }
366 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
367 while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
368 BIO_write(out, iobuf, len);
369 return 1;
370}
371
372/* Split a multipart/XXX message body into component parts: result is
373 * canonical parts in a STACK of bios
374 */
375
376static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
377{
378 char linebuf[MAX_SMLEN];
379 int len, blen;
380 int eol = 0, next_eol = 0;
381 BIO *bpart = NULL;
382 STACK_OF(BIO) *parts;
383 char state, part, first;
384
385 blen = strlen(bound);
386 part = 0;
387 state = 0;
388 first = 1;
389 parts = sk_BIO_new_null();
390 *ret = parts;
391 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
392 state = mime_bound_check(linebuf, len, bound, blen);
393 if(state == 1) {
394 first = 1;
395 part++;
396 } else if(state == 2) {
397 sk_BIO_push(parts, bpart);
398 return 1;
399 } else if(part) {
400 /* Strip CR+LF from linebuf */
401 next_eol = strip_eol(linebuf, &len);
402 if(first) {
403 first = 0;
404 if(bpart) sk_BIO_push(parts, bpart);
405 bpart = BIO_new(BIO_s_mem());
406 BIO_set_mem_eof_return(bpart, 0);
407 } else if (eol)
408 BIO_write(bpart, "\r\n", 2);
409 eol = next_eol;
410 if (len)
411 BIO_write(bpart, linebuf, len);
412 }
413 }
414 return 0;
415}
416
417/* This is the big one: parse MIME header lines up to message body */
418
419#define MIME_INVALID 0
420#define MIME_START 1
421#define MIME_TYPE 2
422#define MIME_NAME 3
423#define MIME_VALUE 4
424#define MIME_QUOTE 5
425#define MIME_COMMENT 6
426
427
428static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
429{
430 char *p, *q, c;
431 char *ntmp;
432 char linebuf[MAX_SMLEN];
433 MIME_HEADER *mhdr = NULL;
434 STACK_OF(MIME_HEADER) *headers;
435 int len, state, save_state = 0;
436
437 headers = sk_MIME_HEADER_new(mime_hdr_cmp);
438 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
439 /* If whitespace at line start then continuation line */
440 if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
441 else state = MIME_START;
442 ntmp = NULL;
443 /* Go through all characters */
444 for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
445
446 /* State machine to handle MIME headers
447 * if this looks horrible that's because it *is*
448 */
449
450 switch(state) {
451 case MIME_START:
452 if(c == ':') {
453 state = MIME_TYPE;
454 *p = 0;
455 ntmp = strip_ends(q);
456 q = p + 1;
457 }
458 break;
459
460 case MIME_TYPE:
461 if(c == ';') {
462 mime_debug("Found End Value\n");
463 *p = 0;
464 mhdr = mime_hdr_new(ntmp, strip_ends(q));
465 sk_MIME_HEADER_push(headers, mhdr);
466 ntmp = NULL;
467 q = p + 1;
468 state = MIME_NAME;
469 } else if(c == '(') {
470 save_state = state;
471 state = MIME_COMMENT;
472 }
473 break;
474
475 case MIME_COMMENT:
476 if(c == ')') {
477 state = save_state;
478 }
479 break;
480
481 case MIME_NAME:
482 if(c == '=') {
483 state = MIME_VALUE;
484 *p = 0;
485 ntmp = strip_ends(q);
486 q = p + 1;
487 }
488 break ;
489
490 case MIME_VALUE:
491 if(c == ';') {
492 state = MIME_NAME;
493 *p = 0;
494 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
495 ntmp = NULL;
496 q = p + 1;
497 } else if (c == '"') {
498 mime_debug("Found Quote\n");
499 state = MIME_QUOTE;
500 } else if(c == '(') {
501 save_state = state;
502 state = MIME_COMMENT;
503 }
504 break;
505
506 case MIME_QUOTE:
507 if(c == '"') {
508 mime_debug("Found Match Quote\n");
509 state = MIME_VALUE;
510 }
511 break;
512 }
513 }
514
515 if(state == MIME_TYPE) {
516 mhdr = mime_hdr_new(ntmp, strip_ends(q));
517 sk_MIME_HEADER_push(headers, mhdr);
518 } else if(state == MIME_VALUE)
519 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
520 if(p == linebuf) break; /* Blank line means end of headers */
521}
522
523return headers;
524
525}
526
527static char *strip_ends(char *name)
528{
529 return strip_end(strip_start(name));
530}
531
532/* Strip a parameter of whitespace from start of param */
533static char *strip_start(char *name)
534{
535 char *p, c;
536 /* Look for first non white space or quote */
537 for(p = name; (c = *p) ;p++) {
538 if(c == '"') {
539 /* Next char is start of string if non null */
540 if(p[1]) return p + 1;
541 /* Else null string */
542 return NULL;
543 }
544 if(!isspace((unsigned char)c)) return p;
545 }
546 return NULL;
547}
548
549/* As above but strip from end of string : maybe should handle brackets? */
550static char *strip_end(char *name)
551{
552 char *p, c;
553 if(!name) return NULL;
554 /* Look for first non white space or quote */
555 for(p = name + strlen(name) - 1; p >= name ;p--) {
556 c = *p;
557 if(c == '"') {
558 if(p - 1 == name) return NULL;
559 *p = 0;
560 return name;
561 }
562 if(isspace((unsigned char)c)) *p = 0;
563 else return name;
564 }
565 return NULL;
566}
567
568static MIME_HEADER *mime_hdr_new(char *name, char *value)
569{
570 MIME_HEADER *mhdr;
571 char *tmpname, *tmpval, *p;
572 int c;
573 if(name) {
574 if(!(tmpname = BUF_strdup(name))) return NULL;
575 for(p = tmpname ; *p; p++) {
576 c = *p;
577 if(isupper(c)) {
578 c = tolower(c);
579 *p = c;
580 }
581 }
582 } else tmpname = NULL;
583 if(value) {
584 if(!(tmpval = BUF_strdup(value))) return NULL;
585 for(p = tmpval ; *p; p++) {
586 c = *p;
587 if(isupper(c)) {
588 c = tolower(c);
589 *p = c;
590 }
591 }
592 } else tmpval = NULL;
593 mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
594 if(!mhdr) return NULL;
595 mhdr->name = tmpname;
596 mhdr->value = tmpval;
597 if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
598 return mhdr;
599}
600
601static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
602{
603 char *tmpname, *tmpval, *p;
604 int c;
605 MIME_PARAM *mparam;
606 if(name) {
607 tmpname = BUF_strdup(name);
608 if(!tmpname) return 0;
609 for(p = tmpname ; *p; p++) {
610 c = *p;
611 if(isupper(c)) {
612 c = tolower(c);
613 *p = c;
614 }
615 }
616 } else tmpname = NULL;
617 if(value) {
618 tmpval = BUF_strdup(value);
619 if(!tmpval) return 0;
620 } else tmpval = NULL;
621 /* Parameter values are case sensitive so leave as is */
622 mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
623 if(!mparam) return 0;
624 mparam->param_name = tmpname;
625 mparam->param_value = tmpval;
626 sk_MIME_PARAM_push(mhdr->params, mparam);
627 return 1;
628}
629
630static int mime_hdr_cmp(const MIME_HEADER * const *a,
631 const MIME_HEADER * const *b)
632{
633 return(strcmp((*a)->name, (*b)->name));
634}
635
636static int mime_param_cmp(const MIME_PARAM * const *a,
637 const MIME_PARAM * const *b)
638{
639 return(strcmp((*a)->param_name, (*b)->param_name));
640}
641
642/* Find a header with a given name (if possible) */
643
644static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
645{
646 MIME_HEADER htmp;
647 int idx;
648 htmp.name = name;
649 idx = sk_MIME_HEADER_find(hdrs, &htmp);
650 if(idx < 0) return NULL;
651 return sk_MIME_HEADER_value(hdrs, idx);
652}
653
654static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
655{
656 MIME_PARAM param;
657 int idx;
658 param.param_name = name;
659 idx = sk_MIME_PARAM_find(hdr->params, &param);
660 if(idx < 0) return NULL;
661 return sk_MIME_PARAM_value(hdr->params, idx);
662}
663
664static void mime_hdr_free(MIME_HEADER *hdr)
665{
666 if(hdr->name) OPENSSL_free(hdr->name);
667 if(hdr->value) OPENSSL_free(hdr->value);
668 if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
669 OPENSSL_free(hdr);
670}
671
672static void mime_param_free(MIME_PARAM *param)
673{
674 if(param->param_name) OPENSSL_free(param->param_name);
675 if(param->param_value) OPENSSL_free(param->param_value);
676 OPENSSL_free(param);
677}
678
679/* Check for a multipart boundary. Returns:
680 * 0 : no boundary
681 * 1 : part boundary
682 * 2 : final boundary
683 */
684static int mime_bound_check(char *line, int linelen, char *bound, int blen)
685{
686 if(linelen == -1) linelen = strlen(line);
687 if(blen == -1) blen = strlen(bound);
688 /* Quickly eliminate if line length too short */
689 if(blen + 2 > linelen) return 0;
690 /* Check for part boundary */
691 if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
692 if(!strncmp(line + blen + 2, "--", 2)) return 2;
693 else return 1;
694 }
695 return 0;
696}
697
698static int strip_eol(char *linebuf, int *plen)
699 {
700 int len = *plen;
701 char *p, c;
702 int is_eol = 0;
703 p = linebuf + len - 1;
704 for (p = linebuf + len - 1; len > 0; len--, p--)
705 {
706 c = *p;
707 if (c == '\n')
708 is_eol = 1;
709 else if (c != '\r')
710 break;
711 }
712 *plen = len;
713 return is_eol;
714 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c
deleted file mode 100644
index 6e5735de11..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_smime.c
+++ /dev/null
@@ -1,441 +0,0 @@
1/* pk7_smime.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59/* Simple PKCS#7 processing functions */
60
61#include <stdio.h>
62#include "cryptlib.h"
63#include <openssl/x509.h>
64#include <openssl/x509v3.h>
65
66PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
67 BIO *data, int flags)
68{
69 PKCS7 *p7;
70 PKCS7_SIGNER_INFO *si;
71 BIO *p7bio;
72 STACK_OF(X509_ALGOR) *smcap;
73 int i;
74
75 if(!X509_check_private_key(signcert, pkey)) {
76 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
77 return NULL;
78 }
79
80 if(!(p7 = PKCS7_new())) {
81 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
82 return NULL;
83 }
84
85 PKCS7_set_type(p7, NID_pkcs7_signed);
86
87 PKCS7_content_new(p7, NID_pkcs7_data);
88
89 if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) {
90 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
91 return NULL;
92 }
93
94 if(!(flags & PKCS7_NOCERTS)) {
95 PKCS7_add_certificate(p7, signcert);
96 if(certs) for(i = 0; i < sk_X509_num(certs); i++)
97 PKCS7_add_certificate(p7, sk_X509_value(certs, i));
98 }
99
100 if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
101 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
102 return NULL;
103 }
104
105
106 SMIME_crlf_copy(data, p7bio, flags);
107
108 if(!(flags & PKCS7_NOATTR)) {
109 PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
110 V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
111 /* Add SMIMECapabilities */
112 if(!(flags & PKCS7_NOSMIMECAP))
113 {
114 if(!(smcap = sk_X509_ALGOR_new_null())) {
115 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
116 return NULL;
117 }
118#ifndef OPENSSL_NO_DES
119 PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1);
120#endif
121#ifndef OPENSSL_NO_RC2
122 PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128);
123 PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64);
124#endif
125#ifndef OPENSSL_NO_DES
126 PKCS7_simple_smimecap (smcap, NID_des_cbc, -1);
127#endif
128#ifndef OPENSSL_NO_RC2
129 PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40);
130#endif
131 PKCS7_add_attrib_smimecap (si, smcap);
132 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
133 }
134 }
135
136 if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1);
137
138 if (!PKCS7_dataFinal(p7,p7bio)) {
139 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN);
140 return NULL;
141 }
142
143 BIO_free_all(p7bio);
144 return p7;
145}
146
147int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
148 BIO *indata, BIO *out, int flags)
149{
150 STACK_OF(X509) *signers;
151 X509 *signer;
152 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
153 PKCS7_SIGNER_INFO *si;
154 X509_STORE_CTX cert_ctx;
155 char buf[4096];
156 int i, j=0, k, ret = 0;
157 BIO *p7bio;
158 BIO *tmpout;
159
160 if(!p7) {
161 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER);
162 return 0;
163 }
164
165 if(!PKCS7_type_is_signed(p7)) {
166 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE);
167 return 0;
168 }
169
170 /* Check for no data and no content: no data to verify signature */
171 if(PKCS7_get_detached(p7) && !indata) {
172 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT);
173 return 0;
174 }
175#if 0
176 /* NB: this test commented out because some versions of Netscape
177 * illegally include zero length content when signing data.
178 */
179
180 /* Check for data and content: two sets of data */
181 if(!PKCS7_get_detached(p7) && indata) {
182 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CONTENT_AND_DATA_PRESENT);
183 return 0;
184 }
185#endif
186
187 sinfos = PKCS7_get_signer_info(p7);
188
189 if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
190 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA);
191 return 0;
192 }
193
194
195 signers = PKCS7_get0_signers(p7, certs, flags);
196
197 if(!signers) return 0;
198
199 /* Now verify the certificates */
200
201 if (!(flags & PKCS7_NOVERIFY)) for (k = 0; k < sk_X509_num(signers); k++) {
202 signer = sk_X509_value (signers, k);
203 if (!(flags & PKCS7_NOCHAIN)) {
204 if(!X509_STORE_CTX_init(&cert_ctx, store, signer,
205 p7->d.sign->cert))
206 {
207 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB);
208 sk_X509_free(signers);
209 return 0;
210 }
211 X509_STORE_CTX_set_purpose(&cert_ctx,
212 X509_PURPOSE_SMIME_SIGN);
213 } else if(!X509_STORE_CTX_init (&cert_ctx, store, signer, NULL)) {
214 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB);
215 sk_X509_free(signers);
216 return 0;
217 }
218 i = X509_verify_cert(&cert_ctx);
219 if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx);
220 X509_STORE_CTX_cleanup(&cert_ctx);
221 if (i <= 0) {
222 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR);
223 ERR_add_error_data(2, "Verify error:",
224 X509_verify_cert_error_string(j));
225 sk_X509_free(signers);
226 return 0;
227 }
228 /* Check for revocation status here */
229 }
230
231 p7bio=PKCS7_dataInit(p7,indata);
232
233 if(flags & PKCS7_TEXT) {
234 if(!(tmpout = BIO_new(BIO_s_mem()))) {
235 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
236 goto err;
237 }
238 } else tmpout = out;
239
240 /* We now have to 'read' from p7bio to calculate digests etc. */
241 for (;;)
242 {
243 i=BIO_read(p7bio,buf,sizeof(buf));
244 if (i <= 0) break;
245 if (tmpout) BIO_write(tmpout, buf, i);
246 }
247
248 if(flags & PKCS7_TEXT) {
249 if(!SMIME_text(tmpout, out)) {
250 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR);
251 BIO_free(tmpout);
252 goto err;
253 }
254 BIO_free(tmpout);
255 }
256
257 /* Now Verify All Signatures */
258 if (!(flags & PKCS7_NOSIGS))
259 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
260 {
261 si=sk_PKCS7_SIGNER_INFO_value(sinfos,i);
262 signer = sk_X509_value (signers, i);
263 j=PKCS7_signatureVerify(p7bio,p7,si, signer);
264 if (j <= 0) {
265 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE);
266 goto err;
267 }
268 }
269
270 ret = 1;
271
272 err:
273
274 if(indata) BIO_pop(p7bio);
275 BIO_free_all(p7bio);
276 sk_X509_free(signers);
277
278 return ret;
279}
280
281STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
282{
283 STACK_OF(X509) *signers;
284 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
285 PKCS7_SIGNER_INFO *si;
286 PKCS7_ISSUER_AND_SERIAL *ias;
287 X509 *signer;
288 int i;
289
290 if(!p7) {
291 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER);
292 return NULL;
293 }
294
295 if(!PKCS7_type_is_signed(p7)) {
296 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE);
297 return NULL;
298 }
299 if(!(signers = sk_X509_new_null())) {
300 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE);
301 return NULL;
302 }
303
304 /* Collect all the signers together */
305
306 sinfos = PKCS7_get_signer_info(p7);
307
308 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
309 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
310 return 0;
311 }
312
313 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
314 {
315 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
316 ias = si->issuer_and_serial;
317 signer = NULL;
318 /* If any certificates passed they take priority */
319 if (certs) signer = X509_find_by_issuer_and_serial (certs,
320 ias->issuer, ias->serial);
321 if (!signer && !(flags & PKCS7_NOINTERN)
322 && p7->d.sign->cert) signer =
323 X509_find_by_issuer_and_serial (p7->d.sign->cert,
324 ias->issuer, ias->serial);
325 if (!signer) {
326 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
327 sk_X509_free(signers);
328 return 0;
329 }
330
331 sk_X509_push(signers, signer);
332 }
333 return signers;
334}
335
336
337/* Build a complete PKCS#7 enveloped data */
338
339PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
340 int flags)
341{
342 PKCS7 *p7;
343 BIO *p7bio = NULL;
344 int i;
345 X509 *x509;
346 if(!(p7 = PKCS7_new())) {
347 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
348 return NULL;
349 }
350
351 PKCS7_set_type(p7, NID_pkcs7_enveloped);
352 if(!PKCS7_set_cipher(p7, cipher)) {
353 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
354 goto err;
355 }
356
357 for(i = 0; i < sk_X509_num(certs); i++) {
358 x509 = sk_X509_value(certs, i);
359 if(!PKCS7_add_recipient(p7, x509)) {
360 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
361 PKCS7_R_ERROR_ADDING_RECIPIENT);
362 goto err;
363 }
364 }
365
366 if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
367 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
368 goto err;
369 }
370
371 SMIME_crlf_copy(in, p7bio, flags);
372
373 BIO_flush(p7bio);
374
375 if (!PKCS7_dataFinal(p7,p7bio)) {
376 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
377 goto err;
378 }
379 BIO_free_all(p7bio);
380
381 return p7;
382
383 err:
384
385 BIO_free(p7bio);
386 PKCS7_free(p7);
387 return NULL;
388
389}
390
391int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
392{
393 BIO *tmpmem;
394 int ret, i;
395 char buf[4096];
396
397 if(!p7) {
398 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER);
399 return 0;
400 }
401
402 if(!PKCS7_type_is_enveloped(p7)) {
403 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE);
404 return 0;
405 }
406
407 if(!X509_check_private_key(cert, pkey)) {
408 PKCS7err(PKCS7_F_PKCS7_DECRYPT,
409 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
410 return 0;
411 }
412
413 if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
414 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
415 return 0;
416 }
417
418 if (flags & PKCS7_TEXT) {
419 BIO *tmpbuf, *bread;
420 /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
421 if(!(tmpbuf = BIO_new(BIO_f_buffer()))) {
422 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
423 return 0;
424 }
425 if(!(bread = BIO_push(tmpbuf, tmpmem))) {
426 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
427 return 0;
428 }
429 ret = SMIME_text(bread, data);
430 BIO_free_all(bread);
431 return ret;
432 } else {
433 for(;;) {
434 i = BIO_read(tmpmem, buf, sizeof(buf));
435 if(i <= 0) break;
436 BIO_write(data, buf, i);
437 }
438 BIO_free_all(tmpmem);
439 return 1;
440 }
441}
diff --git a/src/lib/libcrypto/pkcs7/pkcs7.h b/src/lib/libcrypto/pkcs7/pkcs7.h
deleted file mode 100644
index 15372e18f8..0000000000
--- a/src/lib/libcrypto/pkcs7/pkcs7.h
+++ /dev/null
@@ -1,451 +0,0 @@
1/* crypto/pkcs7/pkcs7.h */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#ifndef HEADER_PKCS7_H
60#define HEADER_PKCS7_H
61
62#include <openssl/asn1.h>
63#include <openssl/bio.h>
64#include <openssl/e_os2.h>
65
66#include <openssl/symhacks.h>
67#include <openssl/ossl_typ.h>
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
73#ifdef OPENSSL_SYS_WIN32
74/* Under Win32 thes are defined in wincrypt.h */
75#undef PKCS7_ISSUER_AND_SERIAL
76#undef PKCS7_SIGNER_INFO
77#endif
78
79/*
80Encryption_ID DES-CBC
81Digest_ID MD5
82Digest_Encryption_ID rsaEncryption
83Key_Encryption_ID rsaEncryption
84*/
85
86typedef struct pkcs7_issuer_and_serial_st
87 {
88 X509_NAME *issuer;
89 ASN1_INTEGER *serial;
90 } PKCS7_ISSUER_AND_SERIAL;
91
92typedef struct pkcs7_signer_info_st
93 {
94 ASN1_INTEGER *version; /* version 1 */
95 PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
96 X509_ALGOR *digest_alg;
97 STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */
98 X509_ALGOR *digest_enc_alg;
99 ASN1_OCTET_STRING *enc_digest;
100 STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
101
102 /* The private key to sign with */
103 EVP_PKEY *pkey;
104 } PKCS7_SIGNER_INFO;
105
106DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
107DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
108
109typedef struct pkcs7_recip_info_st
110 {
111 ASN1_INTEGER *version; /* version 0 */
112 PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
113 X509_ALGOR *key_enc_algor;
114 ASN1_OCTET_STRING *enc_key;
115 X509 *cert; /* get the pub-key from this */
116 } PKCS7_RECIP_INFO;
117
118DECLARE_STACK_OF(PKCS7_RECIP_INFO)
119DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
120
121typedef struct pkcs7_signed_st
122 {
123 ASN1_INTEGER *version; /* version 1 */
124 STACK_OF(X509_ALGOR) *md_algs; /* md used */
125 STACK_OF(X509) *cert; /* [ 0 ] */
126 STACK_OF(X509_CRL) *crl; /* [ 1 ] */
127 STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
128
129 struct pkcs7_st *contents;
130 } PKCS7_SIGNED;
131/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
132 * How about merging the two */
133
134typedef struct pkcs7_enc_content_st
135 {
136 ASN1_OBJECT *content_type;
137 X509_ALGOR *algorithm;
138 ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
139 const EVP_CIPHER *cipher;
140 } PKCS7_ENC_CONTENT;
141
142typedef struct pkcs7_enveloped_st
143 {
144 ASN1_INTEGER *version; /* version 0 */
145 STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
146 PKCS7_ENC_CONTENT *enc_data;
147 } PKCS7_ENVELOPE;
148
149typedef struct pkcs7_signedandenveloped_st
150 {
151 ASN1_INTEGER *version; /* version 1 */
152 STACK_OF(X509_ALGOR) *md_algs; /* md used */
153 STACK_OF(X509) *cert; /* [ 0 ] */
154 STACK_OF(X509_CRL) *crl; /* [ 1 ] */
155 STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
156
157 PKCS7_ENC_CONTENT *enc_data;
158 STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
159 } PKCS7_SIGN_ENVELOPE;
160
161typedef struct pkcs7_digest_st
162 {
163 ASN1_INTEGER *version; /* version 0 */
164 X509_ALGOR *md; /* md used */
165 struct pkcs7_st *contents;
166 ASN1_OCTET_STRING *digest;
167 } PKCS7_DIGEST;
168
169typedef struct pkcs7_encrypted_st
170 {
171 ASN1_INTEGER *version; /* version 0 */
172 PKCS7_ENC_CONTENT *enc_data;
173 } PKCS7_ENCRYPT;
174
175typedef struct pkcs7_st
176 {
177 /* The following is non NULL if it contains ASN1 encoding of
178 * this structure */
179 unsigned char *asn1;
180 long length;
181
182#define PKCS7_S_HEADER 0
183#define PKCS7_S_BODY 1
184#define PKCS7_S_TAIL 2
185 int state; /* used during processing */
186
187 int detached;
188
189 ASN1_OBJECT *type;
190 /* content as defined by the type */
191 /* all encryption/message digests are applied to the 'contents',
192 * leaving out the 'type' field. */
193 union {
194 char *ptr;
195
196 /* NID_pkcs7_data */
197 ASN1_OCTET_STRING *data;
198
199 /* NID_pkcs7_signed */
200 PKCS7_SIGNED *sign;
201
202 /* NID_pkcs7_enveloped */
203 PKCS7_ENVELOPE *enveloped;
204
205 /* NID_pkcs7_signedAndEnveloped */
206 PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
207
208 /* NID_pkcs7_digest */
209 PKCS7_DIGEST *digest;
210
211 /* NID_pkcs7_encrypted */
212 PKCS7_ENCRYPT *encrypted;
213
214 /* Anything else */
215 ASN1_TYPE *other;
216 } d;
217 } PKCS7;
218
219DECLARE_STACK_OF(PKCS7)
220DECLARE_ASN1_SET_OF(PKCS7)
221DECLARE_PKCS12_STACK_OF(PKCS7)
222
223#define PKCS7_OP_SET_DETACHED_SIGNATURE 1
224#define PKCS7_OP_GET_DETACHED_SIGNATURE 2
225
226#define PKCS7_get_signed_attributes(si) ((si)->auth_attr)
227#define PKCS7_get_attributes(si) ((si)->unauth_attr)
228
229#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
230#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
231#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
232#define PKCS7_type_is_signedAndEnveloped(a) \
233 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
234#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
235
236#define PKCS7_set_detached(p,v) \
237 PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
238#define PKCS7_get_detached(p) \
239 PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
240
241#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
242
243#ifdef SSLEAY_MACROS
244#ifndef PKCS7_ISSUER_AND_SERIAL_digest
245#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
246 ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
247 (char *)data,md,len)
248#endif
249#endif
250
251/* S/MIME related flags */
252
253#define PKCS7_TEXT 0x1
254#define PKCS7_NOCERTS 0x2
255#define PKCS7_NOSIGS 0x4
256#define PKCS7_NOCHAIN 0x8
257#define PKCS7_NOINTERN 0x10
258#define PKCS7_NOVERIFY 0x20
259#define PKCS7_DETACHED 0x40
260#define PKCS7_BINARY 0x80
261#define PKCS7_NOATTR 0x100
262#define PKCS7_NOSMIMECAP 0x200
263#define PKCS7_NOOLDMIMETYPE 0x400
264#define PKCS7_CRLFEOL 0x800
265
266/* Flags: for compatibility with older code */
267
268#define SMIME_TEXT PKCS7_TEXT
269#define SMIME_NOCERTS PKCS7_NOCERTS
270#define SMIME_NOSIGS PKCS7_NOSIGS
271#define SMIME_NOCHAIN PKCS7_NOCHAIN
272#define SMIME_NOINTERN PKCS7_NOINTERN
273#define SMIME_NOVERIFY PKCS7_NOVERIFY
274#define SMIME_DETACHED PKCS7_DETACHED
275#define SMIME_BINARY PKCS7_BINARY
276#define SMIME_NOATTR PKCS7_NOATTR
277
278DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
279
280#ifndef SSLEAY_MACROS
281int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
282 unsigned char *md,unsigned int *len);
283#ifndef OPENSSL_NO_FP_API
284PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7);
285int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
286#endif
287PKCS7 *PKCS7_dup(PKCS7 *p7);
288PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
289int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
290#endif
291
292DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
293DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
294DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
295DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
296DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
297DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
298DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
299DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
300DECLARE_ASN1_FUNCTIONS(PKCS7)
301
302DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
303DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
304
305
306long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
307
308int PKCS7_set_type(PKCS7 *p7, int type);
309int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
310int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
311 const EVP_MD *dgst);
312int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
313int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
314int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
315int PKCS7_content_new(PKCS7 *p7, int nid);
316int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
317 BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
318int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
319 X509 *x509);
320
321BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
322int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
323BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
324
325
326PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
327 EVP_PKEY *pkey, const EVP_MD *dgst);
328X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
329STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
330
331PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
332int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
333int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
334int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
335
336PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
337ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
338int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si,int nid,int type,
339 void *data);
340int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
341 void *value);
342ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
343ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
344int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
345 STACK_OF(X509_ATTRIBUTE) *sk);
346int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
347
348
349PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
350 BIO *data, int flags);
351int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
352 BIO *indata, BIO *out, int flags);
353STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
354PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
355 int flags);
356int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
357
358int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
359 STACK_OF(X509_ALGOR) *cap);
360STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
361int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
362
363int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
364PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
365int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
366int SMIME_text(BIO *in, BIO *out);
367
368/* BEGIN ERROR CODES */
369/* The following lines are auto generated by the script mkerr.pl. Any changes
370 * made after this point may be overwritten when the script is next run.
371 */
372void ERR_load_PKCS7_strings(void);
373
374/* Error codes for the PKCS7 functions. */
375
376/* Function codes. */
377#define PKCS7_F_B64_READ_PKCS7 120
378#define PKCS7_F_B64_WRITE_PKCS7 121
379#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118
380#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100
381#define PKCS7_F_PKCS7_ADD_CRL 101
382#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
383#define PKCS7_F_PKCS7_ADD_SIGNER 103
384#define PKCS7_F_PKCS7_CTRL 104
385#define PKCS7_F_PKCS7_DATADECODE 112
386#define PKCS7_F_PKCS7_DATAINIT 105
387#define PKCS7_F_PKCS7_DATASIGN 106
388#define PKCS7_F_PKCS7_DATAVERIFY 107
389#define PKCS7_F_PKCS7_DECRYPT 114
390#define PKCS7_F_PKCS7_ENCRYPT 115
391#define PKCS7_F_PKCS7_GET0_SIGNERS 124
392#define PKCS7_F_PKCS7_SET_CIPHER 108
393#define PKCS7_F_PKCS7_SET_CONTENT 109
394#define PKCS7_F_PKCS7_SET_TYPE 110
395#define PKCS7_F_PKCS7_SIGN 116
396#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
397#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
398#define PKCS7_F_PKCS7_VERIFY 117
399#define PKCS7_F_SMIME_READ_PKCS7 122
400#define PKCS7_F_SMIME_TEXT 123
401
402/* Reason codes. */
403#define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117
404#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144
405#define PKCS7_R_CIPHER_NOT_INITIALIZED 116
406#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118
407#define PKCS7_R_DECODE_ERROR 130
408#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
409#define PKCS7_R_DECRYPT_ERROR 119
410#define PKCS7_R_DIGEST_FAILURE 101
411#define PKCS7_R_ERROR_ADDING_RECIPIENT 120
412#define PKCS7_R_ERROR_SETTING_CIPHER 121
413#define PKCS7_R_INVALID_MIME_TYPE 131
414#define PKCS7_R_INVALID_NULL_POINTER 143
415#define PKCS7_R_MIME_NO_CONTENT_TYPE 132
416#define PKCS7_R_MIME_PARSE_ERROR 133
417#define PKCS7_R_MIME_SIG_PARSE_ERROR 134
418#define PKCS7_R_MISSING_CERIPEND_INFO 103
419#define PKCS7_R_NO_CONTENT 122
420#define PKCS7_R_NO_CONTENT_TYPE 135
421#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136
422#define PKCS7_R_NO_MULTIPART_BOUNDARY 137
423#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
424#define PKCS7_R_NO_SIGNATURES_ON_DATA 123
425#define PKCS7_R_NO_SIGNERS 142
426#define PKCS7_R_NO_SIG_CONTENT_TYPE 138
427#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
428#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
429#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125
430#define PKCS7_R_PKCS7_DATASIGN 126
431#define PKCS7_R_PKCS7_PARSE_ERROR 139
432#define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140
433#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127
434#define PKCS7_R_SIGNATURE_FAILURE 105
435#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128
436#define PKCS7_R_SIG_INVALID_MIME_TYPE 141
437#define PKCS7_R_SMIME_TEXT_ERROR 129
438#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
439#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107
440#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108
441#define PKCS7_R_UNKNOWN_DIGEST_TYPE 109
442#define PKCS7_R_UNKNOWN_OPERATION 110
443#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111
444#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112
445#define PKCS7_R_WRONG_CONTENT_TYPE 113
446#define PKCS7_R_WRONG_PKCS7_TYPE 114
447
448#ifdef __cplusplus
449}
450#endif
451#endif
diff --git a/src/lib/libcrypto/pkcs7/pkcs7err.c b/src/lib/libcrypto/pkcs7/pkcs7err.c
deleted file mode 100644
index 5e51527a40..0000000000
--- a/src/lib/libcrypto/pkcs7/pkcs7err.c
+++ /dev/null
@@ -1,160 +0,0 @@
1/* crypto/pkcs7/pkcs7err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include <openssl/pkcs7.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA PKCS7_str_functs[]=
68 {
69{ERR_PACK(0,PKCS7_F_B64_READ_PKCS7,0), "B64_READ_PKCS7"},
70{ERR_PACK(0,PKCS7_F_B64_WRITE_PKCS7,0), "B64_WRITE_PKCS7"},
71{ERR_PACK(0,PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,0), "PKCS7_add_attrib_smimecap"},
72{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CERTIFICATE,0), "PKCS7_add_certificate"},
73{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CRL,0), "PKCS7_add_crl"},
74{ERR_PACK(0,PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,0), "PKCS7_add_recipient_info"},
75{ERR_PACK(0,PKCS7_F_PKCS7_ADD_SIGNER,0), "PKCS7_add_signer"},
76{ERR_PACK(0,PKCS7_F_PKCS7_CTRL,0), "PKCS7_ctrl"},
77{ERR_PACK(0,PKCS7_F_PKCS7_DATADECODE,0), "PKCS7_dataDecode"},
78{ERR_PACK(0,PKCS7_F_PKCS7_DATAINIT,0), "PKCS7_dataInit"},
79{ERR_PACK(0,PKCS7_F_PKCS7_DATASIGN,0), "PKCS7_DATASIGN"},
80{ERR_PACK(0,PKCS7_F_PKCS7_DATAVERIFY,0), "PKCS7_dataVerify"},
81{ERR_PACK(0,PKCS7_F_PKCS7_DECRYPT,0), "PKCS7_decrypt"},
82{ERR_PACK(0,PKCS7_F_PKCS7_ENCRYPT,0), "PKCS7_encrypt"},
83{ERR_PACK(0,PKCS7_F_PKCS7_GET0_SIGNERS,0), "PKCS7_get0_signers"},
84{ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0), "PKCS7_set_cipher"},
85{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"},
86{ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"},
87{ERR_PACK(0,PKCS7_F_PKCS7_SIGN,0), "PKCS7_sign"},
88{ERR_PACK(0,PKCS7_F_PKCS7_SIGNATUREVERIFY,0), "PKCS7_signatureVerify"},
89{ERR_PACK(0,PKCS7_F_PKCS7_SIMPLE_SMIMECAP,0), "PKCS7_simple_smimecap"},
90{ERR_PACK(0,PKCS7_F_PKCS7_VERIFY,0), "PKCS7_verify"},
91{ERR_PACK(0,PKCS7_F_SMIME_READ_PKCS7,0), "SMIME_read_PKCS7"},
92{ERR_PACK(0,PKCS7_F_SMIME_TEXT,0), "SMIME_text"},
93{0,NULL}
94 };
95
96static ERR_STRING_DATA PKCS7_str_reasons[]=
97 {
98{PKCS7_R_CERTIFICATE_VERIFY_ERROR ,"certificate verify error"},
99{PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER ,"cipher has no object identifier"},
100{PKCS7_R_CIPHER_NOT_INITIALIZED ,"cipher not initialized"},
101{PKCS7_R_CONTENT_AND_DATA_PRESENT ,"content and data present"},
102{PKCS7_R_DECODE_ERROR ,"decode error"},
103{PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH ,"decrypted key is wrong length"},
104{PKCS7_R_DECRYPT_ERROR ,"decrypt error"},
105{PKCS7_R_DIGEST_FAILURE ,"digest failure"},
106{PKCS7_R_ERROR_ADDING_RECIPIENT ,"error adding recipient"},
107{PKCS7_R_ERROR_SETTING_CIPHER ,"error setting cipher"},
108{PKCS7_R_INVALID_MIME_TYPE ,"invalid mime type"},
109{PKCS7_R_INVALID_NULL_POINTER ,"invalid null pointer"},
110{PKCS7_R_MIME_NO_CONTENT_TYPE ,"mime no content type"},
111{PKCS7_R_MIME_PARSE_ERROR ,"mime parse error"},
112{PKCS7_R_MIME_SIG_PARSE_ERROR ,"mime sig parse error"},
113{PKCS7_R_MISSING_CERIPEND_INFO ,"missing ceripend info"},
114{PKCS7_R_NO_CONTENT ,"no content"},
115{PKCS7_R_NO_CONTENT_TYPE ,"no content type"},
116{PKCS7_R_NO_MULTIPART_BODY_FAILURE ,"no multipart body failure"},
117{PKCS7_R_NO_MULTIPART_BOUNDARY ,"no multipart boundary"},
118{PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"},
119{PKCS7_R_NO_SIGNATURES_ON_DATA ,"no signatures on data"},
120{PKCS7_R_NO_SIGNERS ,"no signers"},
121{PKCS7_R_NO_SIG_CONTENT_TYPE ,"no sig content type"},
122{PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this type"},
123{PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR ,"pkcs7 add signature error"},
124{PKCS7_R_PKCS7_DATAFINAL_ERROR ,"pkcs7 datafinal error"},
125{PKCS7_R_PKCS7_DATASIGN ,"pkcs7 datasign"},
126{PKCS7_R_PKCS7_PARSE_ERROR ,"pkcs7 parse error"},
127{PKCS7_R_PKCS7_SIG_PARSE_ERROR ,"pkcs7 sig parse error"},
128{PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE,"private key does not match certificate"},
129{PKCS7_R_SIGNATURE_FAILURE ,"signature failure"},
130{PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND ,"signer certificate not found"},
131{PKCS7_R_SIG_INVALID_MIME_TYPE ,"sig invalid mime type"},
132{PKCS7_R_SMIME_TEXT_ERROR ,"smime text error"},
133{PKCS7_R_UNABLE_TO_FIND_CERTIFICATE ,"unable to find certificate"},
134{PKCS7_R_UNABLE_TO_FIND_MEM_BIO ,"unable to find mem bio"},
135{PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST ,"unable to find message digest"},
136{PKCS7_R_UNKNOWN_DIGEST_TYPE ,"unknown digest type"},
137{PKCS7_R_UNKNOWN_OPERATION ,"unknown operation"},
138{PKCS7_R_UNSUPPORTED_CIPHER_TYPE ,"unsupported cipher type"},
139{PKCS7_R_UNSUPPORTED_CONTENT_TYPE ,"unsupported content type"},
140{PKCS7_R_WRONG_CONTENT_TYPE ,"wrong content type"},
141{PKCS7_R_WRONG_PKCS7_TYPE ,"wrong pkcs7 type"},
142{0,NULL}
143 };
144
145#endif
146
147void ERR_load_PKCS7_strings(void)
148 {
149 static int init=1;
150
151 if (init)
152 {
153 init=0;
154#ifndef OPENSSL_NO_ERR
155 ERR_load_strings(ERR_LIB_PKCS7,PKCS7_str_functs);
156 ERR_load_strings(ERR_LIB_PKCS7,PKCS7_str_reasons);
157#endif
158
159 }
160 }