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.c140
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_doit.c1013
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c500
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_mime.c734
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_smime.c469
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7.h451
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7err.c164
8 files changed, 0 insertions, 3684 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 039141027a..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_attr.c
+++ /dev/null
@@ -1,140 +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-2004 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 || (cap->type != V_ASN1_SEQUENCE))
102 return NULL;
103 p = cap->value.sequence->data;
104 return d2i_ASN1_SET_OF_X509_ALGOR(NULL, &p,
105 cap->value.sequence->length,
106 d2i_X509_ALGOR, X509_ALGOR_free,
107 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
108 }
109
110/* Basic smime-capabilities OID and optional integer arg */
111int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
112{
113 X509_ALGOR *alg;
114
115 if(!(alg = X509_ALGOR_new())) {
116 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
117 return 0;
118 }
119 ASN1_OBJECT_free(alg->algorithm);
120 alg->algorithm = OBJ_nid2obj (nid);
121 if (arg > 0) {
122 ASN1_INTEGER *nbit;
123 if(!(alg->parameter = ASN1_TYPE_new())) {
124 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
125 return 0;
126 }
127 if(!(nbit = ASN1_INTEGER_new())) {
128 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
129 return 0;
130 }
131 if(!ASN1_INTEGER_set (nbit, arg)) {
132 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
133 return 0;
134 }
135 alg->parameter->value.integer = nbit;
136 alg->parameter->type = V_ASN1_INTEGER;
137 }
138 sk_X509_ALGOR_push (sk, alg);
139 return 1;
140}
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
deleted file mode 100644
index 4ac29ae14d..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ /dev/null
@@ -1,1013 +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 ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
95 {
96 if ( PKCS7_type_is_data(p7))
97 return p7->d.data;
98 if ( PKCS7_type_is_other(p7) && p7->d.other
99 && (p7->d.other->type == V_ASN1_OCTET_STRING))
100 return p7->d.other->value.octet_string;
101 return NULL;
102 }
103
104BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
105 {
106 int i;
107 BIO *out=NULL,*btmp=NULL;
108 X509_ALGOR *xa;
109 const EVP_MD *evp_md;
110 const EVP_CIPHER *evp_cipher=NULL;
111 STACK_OF(X509_ALGOR) *md_sk=NULL;
112 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
113 X509_ALGOR *xalg=NULL;
114 PKCS7_RECIP_INFO *ri=NULL;
115 EVP_PKEY *pkey;
116
117 i=OBJ_obj2nid(p7->type);
118 p7->state=PKCS7_S_HEADER;
119
120 switch (i)
121 {
122 case NID_pkcs7_signed:
123 md_sk=p7->d.sign->md_algs;
124 break;
125 case NID_pkcs7_signedAndEnveloped:
126 rsk=p7->d.signed_and_enveloped->recipientinfo;
127 md_sk=p7->d.signed_and_enveloped->md_algs;
128 xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
129 evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
130 if (evp_cipher == NULL)
131 {
132 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
133 PKCS7_R_CIPHER_NOT_INITIALIZED);
134 goto err;
135 }
136 break;
137 case NID_pkcs7_enveloped:
138 rsk=p7->d.enveloped->recipientinfo;
139 xalg=p7->d.enveloped->enc_data->algorithm;
140 evp_cipher=p7->d.enveloped->enc_data->cipher;
141 if (evp_cipher == NULL)
142 {
143 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
144 PKCS7_R_CIPHER_NOT_INITIALIZED);
145 goto err;
146 }
147 break;
148 default:
149 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
150 goto err;
151 }
152
153 if (md_sk != NULL)
154 {
155 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
156 {
157 xa=sk_X509_ALGOR_value(md_sk,i);
158 if ((btmp=BIO_new(BIO_f_md())) == NULL)
159 {
160 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
161 goto err;
162 }
163
164 evp_md=EVP_get_digestbyobj(xa->algorithm);
165 if (evp_md == NULL)
166 {
167 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
168 goto err;
169 }
170
171 BIO_set_md(btmp,evp_md);
172 if (out == NULL)
173 out=btmp;
174 else
175 BIO_push(out,btmp);
176 btmp=NULL;
177 }
178 }
179
180 if (evp_cipher != NULL)
181 {
182 unsigned char key[EVP_MAX_KEY_LENGTH];
183 unsigned char iv[EVP_MAX_IV_LENGTH];
184 int keylen,ivlen;
185 int jj,max;
186 unsigned char *tmp;
187 EVP_CIPHER_CTX *ctx;
188
189 if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
190 {
191 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
192 goto err;
193 }
194 BIO_get_cipher_ctx(btmp, &ctx);
195 keylen=EVP_CIPHER_key_length(evp_cipher);
196 ivlen=EVP_CIPHER_iv_length(evp_cipher);
197 if (RAND_bytes(key,keylen) <= 0)
198 goto err;
199 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
200 if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
201 EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1);
202
203 if (ivlen > 0) {
204 if (xalg->parameter == NULL)
205 xalg->parameter=ASN1_TYPE_new();
206 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
207 goto err;
208 }
209
210 /* Lets do the pub key stuff :-) */
211 max=0;
212 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
213 {
214 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
215 if (ri->cert == NULL)
216 {
217 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
218 goto err;
219 }
220 pkey=X509_get_pubkey(ri->cert);
221 jj=EVP_PKEY_size(pkey);
222 EVP_PKEY_free(pkey);
223 if (max < jj) max=jj;
224 }
225 if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
226 {
227 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
228 goto err;
229 }
230 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
231 {
232 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
233 pkey=X509_get_pubkey(ri->cert);
234 jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
235 EVP_PKEY_free(pkey);
236 if (jj <= 0)
237 {
238 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
239 OPENSSL_free(tmp);
240 goto err;
241 }
242 if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
243 {
244 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
245 ERR_R_MALLOC_FAILURE);
246 OPENSSL_free(tmp);
247 goto err;
248 }
249 }
250 OPENSSL_free(tmp);
251 OPENSSL_cleanse(key, keylen);
252
253 if (out == NULL)
254 out=btmp;
255 else
256 BIO_push(out,btmp);
257 btmp=NULL;
258 }
259
260 if (bio == NULL)
261 {
262 if (PKCS7_is_detached(p7))
263 bio=BIO_new(BIO_s_null());
264 else
265 {
266 if (PKCS7_type_is_signed(p7))
267 {
268 ASN1_OCTET_STRING *os;
269 os = PKCS7_get_octet_string(
270 p7->d.sign->contents);
271 if (os && os->length > 0)
272 bio = BIO_new_mem_buf(os->data,
273 os->length);
274 }
275 if(bio == NULL)
276 {
277 bio=BIO_new(BIO_s_mem());
278 BIO_set_mem_eof_return(bio,0);
279 }
280 }
281 }
282 BIO_push(out,bio);
283 bio=NULL;
284 if (0)
285 {
286err:
287 if (out != NULL)
288 BIO_free_all(out);
289 if (btmp != NULL)
290 BIO_free_all(btmp);
291 out=NULL;
292 }
293 return(out);
294 }
295
296/* int */
297BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
298 {
299 int i,j;
300 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
301 unsigned char *tmp=NULL;
302 X509_ALGOR *xa;
303 ASN1_OCTET_STRING *data_body=NULL;
304 const EVP_MD *evp_md;
305 const EVP_CIPHER *evp_cipher=NULL;
306 EVP_CIPHER_CTX *evp_ctx=NULL;
307 X509_ALGOR *enc_alg=NULL;
308 STACK_OF(X509_ALGOR) *md_sk=NULL;
309 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
310 X509_ALGOR *xalg=NULL;
311 PKCS7_RECIP_INFO *ri=NULL;
312
313 i=OBJ_obj2nid(p7->type);
314 p7->state=PKCS7_S_HEADER;
315
316 switch (i)
317 {
318 case NID_pkcs7_signed:
319 data_body=PKCS7_get_octet_string(p7->d.sign->contents);
320 md_sk=p7->d.sign->md_algs;
321 break;
322 case NID_pkcs7_signedAndEnveloped:
323 rsk=p7->d.signed_and_enveloped->recipientinfo;
324 md_sk=p7->d.signed_and_enveloped->md_algs;
325 data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
326 enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
327 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
328 if (evp_cipher == NULL)
329 {
330 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
331 goto err;
332 }
333 xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
334 break;
335 case NID_pkcs7_enveloped:
336 rsk=p7->d.enveloped->recipientinfo;
337 enc_alg=p7->d.enveloped->enc_data->algorithm;
338 data_body=p7->d.enveloped->enc_data->enc_data;
339 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
340 if (evp_cipher == NULL)
341 {
342 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
343 goto err;
344 }
345 xalg=p7->d.enveloped->enc_data->algorithm;
346 break;
347 default:
348 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
349 goto err;
350 }
351
352 /* We will be checking the signature */
353 if (md_sk != NULL)
354 {
355 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
356 {
357 xa=sk_X509_ALGOR_value(md_sk,i);
358 if ((btmp=BIO_new(BIO_f_md())) == NULL)
359 {
360 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
361 goto err;
362 }
363
364 j=OBJ_obj2nid(xa->algorithm);
365 evp_md=EVP_get_digestbynid(j);
366 if (evp_md == NULL)
367 {
368 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
369 goto err;
370 }
371
372 BIO_set_md(btmp,evp_md);
373 if (out == NULL)
374 out=btmp;
375 else
376 BIO_push(out,btmp);
377 btmp=NULL;
378 }
379 }
380
381 if (evp_cipher != NULL)
382 {
383#if 0
384 unsigned char key[EVP_MAX_KEY_LENGTH];
385 unsigned char iv[EVP_MAX_IV_LENGTH];
386 unsigned char *p;
387 int keylen,ivlen;
388 int max;
389 X509_OBJECT ret;
390#endif
391 int jj;
392
393 if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
394 {
395 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
396 goto err;
397 }
398
399 /* It was encrypted, we need to decrypt the secret key
400 * with the private key */
401
402 /* Find the recipientInfo which matches the passed certificate
403 * (if any)
404 */
405
406 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
407 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
408 if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
409 pcert->cert_info->issuer) &&
410 !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
411 ri->issuer_and_serial->serial)) break;
412 ri=NULL;
413 }
414 if (ri == NULL) {
415 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
416 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
417 goto err;
418 }
419
420 jj=EVP_PKEY_size(pkey);
421 tmp=(unsigned char *)OPENSSL_malloc(jj+10);
422 if (tmp == NULL)
423 {
424 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
425 goto err;
426 }
427
428 jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key),
429 M_ASN1_STRING_length(ri->enc_key), pkey);
430 if (jj <= 0)
431 {
432 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
433 goto err;
434 }
435
436 evp_ctx=NULL;
437 BIO_get_cipher_ctx(etmp,&evp_ctx);
438 EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0);
439 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
440 goto err;
441
442 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
443 /* Some S/MIME clients don't use the same key
444 * and effective key length. The key length is
445 * determined by the size of the decrypted RSA key.
446 */
447 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
448 {
449 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
450 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
451 goto err;
452 }
453 }
454 EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0);
455
456 OPENSSL_cleanse(tmp,jj);
457
458 if (out == NULL)
459 out=etmp;
460 else
461 BIO_push(out,etmp);
462 etmp=NULL;
463 }
464
465#if 1
466 if (PKCS7_is_detached(p7) || (in_bio != NULL))
467 {
468 bio=in_bio;
469 }
470 else
471 {
472#if 0
473 bio=BIO_new(BIO_s_mem());
474 /* We need to set this so that when we have read all
475 * the data, the encrypt BIO, if present, will read
476 * EOF and encode the last few bytes */
477 BIO_set_mem_eof_return(bio,0);
478
479 if (data_body->length > 0)
480 BIO_write(bio,(char *)data_body->data,data_body->length);
481#else
482 if (data_body->length > 0)
483 bio = BIO_new_mem_buf(data_body->data,data_body->length);
484 else {
485 bio=BIO_new(BIO_s_mem());
486 BIO_set_mem_eof_return(bio,0);
487 }
488#endif
489 }
490 BIO_push(out,bio);
491 bio=NULL;
492#endif
493 if (0)
494 {
495err:
496 if (out != NULL) BIO_free_all(out);
497 if (btmp != NULL) BIO_free_all(btmp);
498 if (etmp != NULL) BIO_free_all(etmp);
499 if (bio != NULL) BIO_free_all(bio);
500 out=NULL;
501 }
502 if (tmp != NULL)
503 OPENSSL_free(tmp);
504 return(out);
505 }
506
507int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
508 {
509 int ret=0;
510 int i,j;
511 BIO *btmp;
512 BUF_MEM *buf_mem=NULL;
513 BUF_MEM *buf=NULL;
514 PKCS7_SIGNER_INFO *si;
515 EVP_MD_CTX *mdc,ctx_tmp;
516 STACK_OF(X509_ATTRIBUTE) *sk;
517 STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
518 ASN1_OCTET_STRING *os=NULL;
519
520 EVP_MD_CTX_init(&ctx_tmp);
521 i=OBJ_obj2nid(p7->type);
522 p7->state=PKCS7_S_HEADER;
523
524 switch (i)
525 {
526 case NID_pkcs7_signedAndEnveloped:
527 /* XXXXXXXXXXXXXXXX */
528 si_sk=p7->d.signed_and_enveloped->signer_info;
529 if (!(os=M_ASN1_OCTET_STRING_new()))
530 {
531 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_MALLOC_FAILURE);
532 goto err;
533 }
534 p7->d.signed_and_enveloped->enc_data->enc_data=os;
535 break;
536 case NID_pkcs7_enveloped:
537 /* XXXXXXXXXXXXXXXX */
538 if (!(os=M_ASN1_OCTET_STRING_new()))
539 {
540 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_MALLOC_FAILURE);
541 goto err;
542 }
543 p7->d.enveloped->enc_data->enc_data=os;
544 break;
545 case NID_pkcs7_signed:
546 si_sk=p7->d.sign->signer_info;
547 os=PKCS7_get_octet_string(p7->d.sign->contents);
548 /* If detached data then the content is excluded */
549 if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
550 M_ASN1_OCTET_STRING_free(os);
551 p7->d.sign->contents->d.data = NULL;
552 }
553 break;
554 }
555
556 if (si_sk != NULL)
557 {
558 if ((buf=BUF_MEM_new()) == NULL)
559 {
560 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
561 goto err;
562 }
563 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
564 {
565 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
566 if (si->pkey == NULL) continue;
567
568 j=OBJ_obj2nid(si->digest_alg->algorithm);
569
570 btmp=bio;
571 for (;;)
572 {
573 if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD))
574 == NULL)
575 {
576 PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
577 goto err;
578 }
579 BIO_get_md_ctx(btmp,&mdc);
580 if (mdc == NULL)
581 {
582 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR);
583 goto err;
584 }
585 if (EVP_MD_CTX_type(mdc) == j)
586 break;
587 else
588 btmp=BIO_next(btmp);
589 }
590
591 /* We now have the EVP_MD_CTX, lets do the
592 * signing. */
593 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
594 if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
595 {
596 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
597 goto err;
598 }
599
600 sk=si->auth_attr;
601
602 /* If there are attributes, we add the digest
603 * attribute and only sign the attributes */
604 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
605 {
606 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
607 unsigned int md_len, alen;
608 ASN1_OCTET_STRING *digest;
609 ASN1_UTCTIME *sign_time;
610 const EVP_MD *md_tmp;
611
612 /* Add signing time if not already present */
613 if (!PKCS7_get_signed_attribute(si,
614 NID_pkcs9_signingTime))
615 {
616 if (!(sign_time=X509_gmtime_adj(NULL,0)))
617 {
618 PKCS7err(PKCS7_F_PKCS7_DATASIGN,
619 ERR_R_MALLOC_FAILURE);
620 goto err;
621 }
622 PKCS7_add_signed_attribute(si,
623 NID_pkcs9_signingTime,
624 V_ASN1_UTCTIME,sign_time);
625 }
626
627 /* Add digest */
628 md_tmp=EVP_MD_CTX_md(&ctx_tmp);
629 EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
630 if (!(digest=M_ASN1_OCTET_STRING_new()))
631 {
632 PKCS7err(PKCS7_F_PKCS7_DATASIGN,
633 ERR_R_MALLOC_FAILURE);
634 goto err;
635 }
636 if (!M_ASN1_OCTET_STRING_set(digest,md_data,
637 md_len))
638 {
639 PKCS7err(PKCS7_F_PKCS7_DATASIGN,
640 ERR_R_MALLOC_FAILURE);
641 goto err;
642 }
643 PKCS7_add_signed_attribute(si,
644 NID_pkcs9_messageDigest,
645 V_ASN1_OCTET_STRING,digest);
646
647 /* Now sign the attributes */
648 EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
649 alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
650 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
651 if(!abuf) goto err;
652 EVP_SignUpdate(&ctx_tmp,abuf,alen);
653 OPENSSL_free(abuf);
654 }
655
656#ifndef OPENSSL_NO_DSA
657 if (si->pkey->type == EVP_PKEY_DSA)
658 ctx_tmp.digest=EVP_dss1();
659#endif
660
661 if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
662 (unsigned int *)&buf->length,si->pkey))
663 {
664 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB);
665 goto err;
666 }
667 if (!ASN1_STRING_set(si->enc_digest,
668 (unsigned char *)buf->data,buf->length))
669 {
670 PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB);
671 goto err;
672 }
673 }
674 }
675
676 if (!PKCS7_is_detached(p7))
677 {
678 btmp=BIO_find_type(bio,BIO_TYPE_MEM);
679 if (btmp == NULL)
680 {
681 PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
682 goto err;
683 }
684 BIO_get_mem_ptr(btmp,&buf_mem);
685 /* Mark the BIO read only then we can use its copy of the data
686 * instead of making an extra copy.
687 */
688 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
689 BIO_set_mem_eof_return(btmp, 0);
690 os->data = (unsigned char *)buf_mem->data;
691 os->length = buf_mem->length;
692#if 0
693 M_ASN1_OCTET_STRING_set(os,
694 (unsigned char *)buf_mem->data,buf_mem->length);
695#endif
696 }
697 ret=1;
698err:
699 EVP_MD_CTX_cleanup(&ctx_tmp);
700 if (buf != NULL) BUF_MEM_free(buf);
701 return(ret);
702 }
703
704int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
705 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
706 {
707 PKCS7_ISSUER_AND_SERIAL *ias;
708 int ret=0,i;
709 STACK_OF(X509) *cert;
710 X509 *x509;
711
712 if (PKCS7_type_is_signed(p7))
713 {
714 cert=p7->d.sign->cert;
715 }
716 else if (PKCS7_type_is_signedAndEnveloped(p7))
717 {
718 cert=p7->d.signed_and_enveloped->cert;
719 }
720 else
721 {
722 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);
723 goto err;
724 }
725 /* XXXXXXXXXXXXXXXXXXXXXXX */
726 ias=si->issuer_and_serial;
727
728 x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);
729
730 /* were we able to find the cert in passed to us */
731 if (x509 == NULL)
732 {
733 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
734 goto err;
735 }
736
737 /* Lets verify */
738 if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
739 {
740 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
741 goto err;
742 }
743 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
744 i=X509_verify_cert(ctx);
745 if (i <= 0)
746 {
747 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
748 X509_STORE_CTX_cleanup(ctx);
749 goto err;
750 }
751 X509_STORE_CTX_cleanup(ctx);
752
753 return PKCS7_signatureVerify(bio, p7, si, x509);
754 err:
755 return ret;
756 }
757
758int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
759 X509 *x509)
760 {
761 ASN1_OCTET_STRING *os;
762 EVP_MD_CTX mdc_tmp,*mdc;
763 int ret=0,i;
764 int md_type;
765 STACK_OF(X509_ATTRIBUTE) *sk;
766 BIO *btmp;
767 EVP_PKEY *pkey;
768
769 EVP_MD_CTX_init(&mdc_tmp);
770
771 if (!PKCS7_type_is_signed(p7) &&
772 !PKCS7_type_is_signedAndEnveloped(p7)) {
773 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
774 PKCS7_R_WRONG_PKCS7_TYPE);
775 goto err;
776 }
777
778 md_type=OBJ_obj2nid(si->digest_alg->algorithm);
779
780 btmp=bio;
781 for (;;)
782 {
783 if ((btmp == NULL) ||
784 ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
785 {
786 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
787 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
788 goto err;
789 }
790 BIO_get_md_ctx(btmp,&mdc);
791 if (mdc == NULL)
792 {
793 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
794 ERR_R_INTERNAL_ERROR);
795 goto err;
796 }
797 if (EVP_MD_CTX_type(mdc) == md_type)
798 break;
799 /* Workaround for some broken clients that put the signature
800 * OID instead of the digest OID in digest_alg->algorithm
801 */
802 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
803 break;
804 btmp=BIO_next(btmp);
805 }
806
807 /* mdc is the digest ctx that we want, unless there are attributes,
808 * in which case the digest is the signed attributes */
809 EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);
810
811 sk=si->auth_attr;
812 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
813 {
814 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
815 unsigned int md_len, alen;
816 ASN1_OCTET_STRING *message_digest;
817
818 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
819 message_digest=PKCS7_digest_from_attributes(sk);
820 if (!message_digest)
821 {
822 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
823 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
824 goto err;
825 }
826 if ((message_digest->length != (int)md_len) ||
827 (memcmp(message_digest->data,md_dat,md_len)))
828 {
829#if 0
830{
831int ii;
832for (ii=0; ii<message_digest->length; ii++)
833 printf("%02X",message_digest->data[ii]); printf(" sent\n");
834for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
835}
836#endif
837 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
838 PKCS7_R_DIGEST_FAILURE);
839 ret= -1;
840 goto err;
841 }
842
843 EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);
844
845 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
846 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
847 EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
848
849 OPENSSL_free(abuf);
850 }
851
852 os=si->enc_digest;
853 pkey = X509_get_pubkey(x509);
854 if (!pkey)
855 {
856 ret = -1;
857 goto err;
858 }
859#ifndef OPENSSL_NO_DSA
860 if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
861#endif
862
863 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
864 EVP_PKEY_free(pkey);
865 if (i <= 0)
866 {
867 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
868 PKCS7_R_SIGNATURE_FAILURE);
869 ret= -1;
870 goto err;
871 }
872 else
873 ret=1;
874err:
875 EVP_MD_CTX_cleanup(&mdc_tmp);
876 return(ret);
877 }
878
879PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
880 {
881 STACK_OF(PKCS7_RECIP_INFO) *rsk;
882 PKCS7_RECIP_INFO *ri;
883 int i;
884
885 i=OBJ_obj2nid(p7->type);
886 if (i != NID_pkcs7_signedAndEnveloped) return(NULL);
887 rsk=p7->d.signed_and_enveloped->recipientinfo;
888 ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
889 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
890 ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
891 return(ri->issuer_and_serial);
892 }
893
894ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
895 {
896 return(get_attribute(si->auth_attr,nid));
897 }
898
899ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
900 {
901 return(get_attribute(si->unauth_attr,nid));
902 }
903
904static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
905 {
906 int i;
907 X509_ATTRIBUTE *xa;
908 ASN1_OBJECT *o;
909
910 o=OBJ_nid2obj(nid);
911 if (!o || !sk) return(NULL);
912 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
913 {
914 xa=sk_X509_ATTRIBUTE_value(sk,i);
915 if (OBJ_cmp(xa->object,o) == 0)
916 {
917 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
918 return(sk_ASN1_TYPE_value(xa->value.set,0));
919 else
920 return(NULL);
921 }
922 }
923 return(NULL);
924 }
925
926ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
927{
928 ASN1_TYPE *astype;
929 if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
930 return astype->value.octet_string;
931}
932
933int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
934 STACK_OF(X509_ATTRIBUTE) *sk)
935 {
936 int i;
937
938 if (p7si->auth_attr != NULL)
939 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
940 p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
941 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
942 {
943 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
944 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
945 == NULL)
946 return(0);
947 }
948 return(1);
949 }
950
951int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
952 {
953 int i;
954
955 if (p7si->unauth_attr != NULL)
956 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
957 X509_ATTRIBUTE_free);
958 p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
959 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
960 {
961 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
962 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
963 == NULL)
964 return(0);
965 }
966 return(1);
967 }
968
969int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
970 void *value)
971 {
972 return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
973 }
974
975int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
976 void *value)
977 {
978 return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
979 }
980
981static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
982 void *value)
983 {
984 X509_ATTRIBUTE *attr=NULL;
985
986 if (*sk == NULL)
987 {
988 *sk = sk_X509_ATTRIBUTE_new_null();
989new_attrib:
990 attr=X509_ATTRIBUTE_create(nid,atrtype,value);
991 sk_X509_ATTRIBUTE_push(*sk,attr);
992 }
993 else
994 {
995 int i;
996
997 for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++)
998 {
999 attr=sk_X509_ATTRIBUTE_value(*sk,i);
1000 if (OBJ_obj2nid(attr->object) == nid)
1001 {
1002 X509_ATTRIBUTE_free(attr);
1003 attr=X509_ATTRIBUTE_create(nid,atrtype,value);
1004 sk_X509_ATTRIBUTE_set(*sk,i,attr);
1005 goto end;
1006 }
1007 }
1008 goto new_attrib;
1009 }
1010end:
1011 return(1);
1012 }
1013
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
deleted file mode 100644
index ee1817c7af..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ /dev/null
@@ -1,500 +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 if (!ASN1_INTEGER_set(p7->d.sign->version,1))
168 {
169 PKCS7_SIGNED_free(p7->d.sign);
170 p7->d.sign=NULL;
171 goto err;
172 }
173 break;
174 case NID_pkcs7_data:
175 p7->type=obj;
176 if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
177 goto err;
178 break;
179 case NID_pkcs7_signedAndEnveloped:
180 p7->type=obj;
181 if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
182 == NULL) goto err;
183 ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
184 if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1))
185 goto err;
186 p7->d.signed_and_enveloped->enc_data->content_type
187 = OBJ_nid2obj(NID_pkcs7_data);
188 break;
189 case NID_pkcs7_enveloped:
190 p7->type=obj;
191 if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
192 == NULL) goto err;
193 if (!ASN1_INTEGER_set(p7->d.enveloped->version,0))
194 goto err;
195 p7->d.enveloped->enc_data->content_type
196 = OBJ_nid2obj(NID_pkcs7_data);
197 break;
198 case NID_pkcs7_encrypted:
199 p7->type=obj;
200 if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
201 == NULL) goto err;
202 if (!ASN1_INTEGER_set(p7->d.encrypted->version,0))
203 goto err;
204 p7->d.encrypted->enc_data->content_type
205 = OBJ_nid2obj(NID_pkcs7_data);
206 break;
207
208 case NID_pkcs7_digest:
209 default:
210 PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
211 goto err;
212 }
213 return(1);
214err:
215 return(0);
216 }
217
218int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
219 {
220 int i,j,nid;
221 X509_ALGOR *alg;
222 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
223 STACK_OF(X509_ALGOR) *md_sk;
224
225 i=OBJ_obj2nid(p7->type);
226 switch (i)
227 {
228 case NID_pkcs7_signed:
229 signer_sk= p7->d.sign->signer_info;
230 md_sk= p7->d.sign->md_algs;
231 break;
232 case NID_pkcs7_signedAndEnveloped:
233 signer_sk= p7->d.signed_and_enveloped->signer_info;
234 md_sk= p7->d.signed_and_enveloped->md_algs;
235 break;
236 default:
237 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
238 return(0);
239 }
240
241 nid=OBJ_obj2nid(psi->digest_alg->algorithm);
242
243 /* If the digest is not currently listed, add it */
244 j=0;
245 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
246 {
247 alg=sk_X509_ALGOR_value(md_sk,i);
248 if (OBJ_obj2nid(alg->algorithm) == nid)
249 {
250 j=1;
251 break;
252 }
253 }
254 if (!j) /* we need to add another algorithm */
255 {
256 if(!(alg=X509_ALGOR_new())
257 || !(alg->parameter = ASN1_TYPE_new())) {
258 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
259 return(0);
260 }
261 alg->algorithm=OBJ_nid2obj(nid);
262 alg->parameter->type = V_ASN1_NULL;
263 sk_X509_ALGOR_push(md_sk,alg);
264 }
265
266 sk_PKCS7_SIGNER_INFO_push(signer_sk,psi);
267 return(1);
268 }
269
270int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
271 {
272 int i;
273 STACK_OF(X509) **sk;
274
275 i=OBJ_obj2nid(p7->type);
276 switch (i)
277 {
278 case NID_pkcs7_signed:
279 sk= &(p7->d.sign->cert);
280 break;
281 case NID_pkcs7_signedAndEnveloped:
282 sk= &(p7->d.signed_and_enveloped->cert);
283 break;
284 default:
285 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE);
286 return(0);
287 }
288
289 if (*sk == NULL)
290 *sk=sk_X509_new_null();
291 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
292 sk_X509_push(*sk,x509);
293 return(1);
294 }
295
296int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
297 {
298 int i;
299 STACK_OF(X509_CRL) **sk;
300
301 i=OBJ_obj2nid(p7->type);
302 switch (i)
303 {
304 case NID_pkcs7_signed:
305 sk= &(p7->d.sign->crl);
306 break;
307 case NID_pkcs7_signedAndEnveloped:
308 sk= &(p7->d.signed_and_enveloped->crl);
309 break;
310 default:
311 PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE);
312 return(0);
313 }
314
315 if (*sk == NULL)
316 *sk=sk_X509_CRL_new_null();
317
318 CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
319 sk_X509_CRL_push(*sk,crl);
320 return(1);
321 }
322
323int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
324 const EVP_MD *dgst)
325 {
326 char is_dsa;
327 if (pkey->type == EVP_PKEY_DSA) is_dsa = 1;
328 else is_dsa = 0;
329 /* We now need to add another PKCS7_SIGNER_INFO entry */
330 if (!ASN1_INTEGER_set(p7i->version,1))
331 goto err;
332 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
333 X509_get_issuer_name(x509)))
334 goto err;
335
336 /* because ASN1_INTEGER_set is used to set a 'long' we will do
337 * things the ugly way. */
338 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
339 if (!(p7i->issuer_and_serial->serial=
340 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
341 goto err;
342
343 /* lets keep the pkey around for a while */
344 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
345 p7i->pkey=pkey;
346
347 /* Set the algorithms */
348 if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
349 else
350 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
351
352 if (p7i->digest_alg->parameter != NULL)
353 ASN1_TYPE_free(p7i->digest_alg->parameter);
354 if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
355 goto err;
356 p7i->digest_alg->parameter->type=V_ASN1_NULL;
357
358 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(EVP_PKEY_type(pkey->type));
359
360 if (p7i->digest_enc_alg->parameter != NULL)
361 ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
362 if(is_dsa) p7i->digest_enc_alg->parameter = NULL;
363 else {
364 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
365 goto err;
366 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
367 }
368
369 return(1);
370err:
371 return(0);
372 }
373
374PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
375 const EVP_MD *dgst)
376 {
377 PKCS7_SIGNER_INFO *si;
378
379 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
380 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
381 if (!PKCS7_add_signer(p7,si)) goto err;
382 return(si);
383err:
384 return(NULL);
385 }
386
387STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
388 {
389 if (PKCS7_type_is_signed(p7))
390 {
391 return(p7->d.sign->signer_info);
392 }
393 else if (PKCS7_type_is_signedAndEnveloped(p7))
394 {
395 return(p7->d.signed_and_enveloped->signer_info);
396 }
397 else
398 return(NULL);
399 }
400
401PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
402 {
403 PKCS7_RECIP_INFO *ri;
404
405 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
406 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
407 if (!PKCS7_add_recipient_info(p7,ri)) goto err;
408 return(ri);
409err:
410 return(NULL);
411 }
412
413int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
414 {
415 int i;
416 STACK_OF(PKCS7_RECIP_INFO) *sk;
417
418 i=OBJ_obj2nid(p7->type);
419 switch (i)
420 {
421 case NID_pkcs7_signedAndEnveloped:
422 sk= p7->d.signed_and_enveloped->recipientinfo;
423 break;
424 case NID_pkcs7_enveloped:
425 sk= p7->d.enveloped->recipientinfo;
426 break;
427 default:
428 PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE);
429 return(0);
430 }
431
432 sk_PKCS7_RECIP_INFO_push(sk,ri);
433 return(1);
434 }
435
436int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
437 {
438 if (!ASN1_INTEGER_set(p7i->version,0))
439 return 0;
440 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
441 X509_get_issuer_name(x509)))
442 return 0;
443
444 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
445 if (!(p7i->issuer_and_serial->serial=
446 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
447 return 0;
448
449 X509_ALGOR_free(p7i->key_enc_algor);
450 if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor)))
451 return 0;
452
453 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
454 p7i->cert=x509;
455
456 return(1);
457 }
458
459X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
460 {
461 if (PKCS7_type_is_signed(p7))
462 return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
463 si->issuer_and_serial->issuer,
464 si->issuer_and_serial->serial));
465 else
466 return(NULL);
467 }
468
469int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
470 {
471 int i;
472 ASN1_OBJECT *objtmp;
473 PKCS7_ENC_CONTENT *ec;
474
475 i=OBJ_obj2nid(p7->type);
476 switch (i)
477 {
478 case NID_pkcs7_signedAndEnveloped:
479 ec=p7->d.signed_and_enveloped->enc_data;
480 break;
481 case NID_pkcs7_enveloped:
482 ec=p7->d.enveloped->enc_data;
483 break;
484 default:
485 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE);
486 return(0);
487 }
488
489 /* Check cipher OID exists and has data in it*/
490 i = EVP_CIPHER_type(cipher);
491 if(i == NID_undef) {
492 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
493 return(0);
494 }
495 objtmp = OBJ_nid2obj(i);
496
497 ec->cipher = cipher;
498 return 1;
499 }
500
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c
deleted file mode 100644
index 927b88c3e7..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_mime.c
+++ /dev/null
@@ -1,734 +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-2005 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, *msg_type=NULL;
156 if (flags & PKCS7_NOOLDMIMETYPE)
157 mime_prefix = "application/pkcs7-";
158 else
159 mime_prefix = "application/x-pkcs7-";
160
161 if (flags & PKCS7_CRLFEOL)
162 mime_eol = "\r\n";
163 else
164 mime_eol = "\n";
165 if((flags & PKCS7_DETACHED) && data) {
166 /* We want multipart/signed */
167 /* Generate a random boundary */
168 RAND_pseudo_bytes((unsigned char *)bound, 32);
169 for(i = 0; i < 32; i++) {
170 c = bound[i] & 0xf;
171 if(c < 10) c += '0';
172 else c += 'A' - 10;
173 bound[i] = c;
174 }
175 bound[32] = 0;
176 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
177 BIO_printf(bio, "Content-Type: multipart/signed;");
178 BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
179 BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"%s%s",
180 bound, mime_eol, mime_eol);
181 BIO_printf(bio, "This is an S/MIME signed message%s%s",
182 mime_eol, mime_eol);
183 /* Now write out the first part */
184 BIO_printf(bio, "------%s%s", bound, mime_eol);
185 SMIME_crlf_copy(data, bio, flags);
186 BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
187
188 /* Headers for signature */
189
190 BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
191 BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
192 BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
193 mime_eol);
194 BIO_printf(bio, "Content-Disposition: attachment;");
195 BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
196 mime_eol, mime_eol);
197 B64_write_PKCS7(bio, p7);
198 BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
199 mime_eol, mime_eol);
200 return 1;
201 }
202
203 /* Determine smime-type header */
204
205 if (PKCS7_type_is_enveloped(p7))
206 msg_type = "enveloped-data";
207 else if (PKCS7_type_is_signed(p7))
208 {
209 /* If we have any signers it is signed-data othewise
210 * certs-only.
211 */
212 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
213 sinfos = PKCS7_get_signer_info(p7);
214 if (sk_PKCS7_SIGNER_INFO_num(sinfos) > 0)
215 msg_type = "signed-data";
216 else
217 msg_type = "certs-only";
218 }
219 /* MIME headers */
220 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
221 BIO_printf(bio, "Content-Disposition: attachment;");
222 BIO_printf(bio, " filename=\"smime.p7m\"%s", mime_eol);
223 BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
224 if (msg_type)
225 BIO_printf(bio, " smime-type=%s;", msg_type);
226 BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol);
227 BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
228 mime_eol, mime_eol);
229 B64_write_PKCS7(bio, p7);
230 BIO_printf(bio, "%s", mime_eol);
231 return 1;
232}
233
234/* SMIME reader: handle multipart/signed and opaque signing.
235 * in multipart case the content is placed in a memory BIO
236 * pointed to by "bcont". In opaque this is set to NULL
237 */
238
239PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
240{
241 BIO *p7in;
242 STACK_OF(MIME_HEADER) *headers = NULL;
243 STACK_OF(BIO) *parts = NULL;
244 MIME_HEADER *hdr;
245 MIME_PARAM *prm;
246 PKCS7 *p7;
247 int ret;
248
249 if(bcont) *bcont = NULL;
250
251 if (!(headers = mime_parse_hdr(bio))) {
252 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_PARSE_ERROR);
253 return NULL;
254 }
255
256 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
257 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
258 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_CONTENT_TYPE);
259 return NULL;
260 }
261
262 /* Handle multipart/signed */
263
264 if(!strcmp(hdr->value, "multipart/signed")) {
265 /* Split into two parts */
266 prm = mime_param_find(hdr, "boundary");
267 if(!prm || !prm->param_value) {
268 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
269 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BOUNDARY);
270 return NULL;
271 }
272 ret = multi_split(bio, prm->param_value, &parts);
273 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
274 if(!ret || (sk_BIO_num(parts) != 2) ) {
275 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BODY_FAILURE);
276 sk_BIO_pop_free(parts, BIO_vfree);
277 return NULL;
278 }
279
280 /* Parse the signature piece */
281 p7in = sk_BIO_value(parts, 1);
282
283 if (!(headers = mime_parse_hdr(p7in))) {
284 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_SIG_PARSE_ERROR);
285 sk_BIO_pop_free(parts, BIO_vfree);
286 return NULL;
287 }
288
289 /* Get content type */
290
291 if(!(hdr = mime_hdr_find(headers, "content-type")) ||
292 !hdr->value) {
293 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
294 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_SIG_CONTENT_TYPE);
295 return NULL;
296 }
297
298 if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
299 strcmp(hdr->value, "application/pkcs7-signature")) {
300 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
301 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_SIG_INVALID_MIME_TYPE);
302 ERR_add_error_data(2, "type: ", hdr->value);
303 sk_BIO_pop_free(parts, BIO_vfree);
304 return NULL;
305 }
306 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
307 /* Read in PKCS#7 */
308 if(!(p7 = B64_read_PKCS7(p7in))) {
309 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_PKCS7_SIG_PARSE_ERROR);
310 sk_BIO_pop_free(parts, BIO_vfree);
311 return NULL;
312 }
313
314 if(bcont) {
315 *bcont = sk_BIO_value(parts, 0);
316 BIO_free(p7in);
317 sk_BIO_free(parts);
318 } else sk_BIO_pop_free(parts, BIO_vfree);
319 return p7;
320 }
321
322 /* OK, if not multipart/signed try opaque signature */
323
324 if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
325 strcmp (hdr->value, "application/pkcs7-mime")) {
326 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_INVALID_MIME_TYPE);
327 ERR_add_error_data(2, "type: ", hdr->value);
328 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
329 return NULL;
330 }
331
332 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
333
334 if(!(p7 = B64_read_PKCS7(bio))) {
335 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_PKCS7_PARSE_ERROR);
336 return NULL;
337 }
338 return p7;
339
340}
341
342/* Copy text from one BIO to another making the output CRLF at EOL */
343int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
344{
345 char eol;
346 int len;
347 char linebuf[MAX_SMLEN];
348 if(flags & PKCS7_BINARY) {
349 while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
350 BIO_write(out, linebuf, len);
351 return 1;
352 }
353 if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
354 while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
355 eol = strip_eol(linebuf, &len);
356 if (len)
357 BIO_write(out, linebuf, len);
358 if(eol) BIO_write(out, "\r\n", 2);
359 }
360 return 1;
361}
362
363/* Strip off headers if they are text/plain */
364int SMIME_text(BIO *in, BIO *out)
365{
366 char iobuf[4096];
367 int len;
368 STACK_OF(MIME_HEADER) *headers;
369 MIME_HEADER *hdr;
370
371 if (!(headers = mime_parse_hdr(in))) {
372 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR);
373 return 0;
374 }
375 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
376 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE);
377 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
378 return 0;
379 }
380 if (strcmp (hdr->value, "text/plain")) {
381 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE);
382 ERR_add_error_data(2, "type: ", hdr->value);
383 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
384 return 0;
385 }
386 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
387 while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
388 BIO_write(out, iobuf, len);
389 return 1;
390}
391
392/* Split a multipart/XXX message body into component parts: result is
393 * canonical parts in a STACK of bios
394 */
395
396static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
397{
398 char linebuf[MAX_SMLEN];
399 int len, blen;
400 int eol = 0, next_eol = 0;
401 BIO *bpart = NULL;
402 STACK_OF(BIO) *parts;
403 char state, part, first;
404
405 blen = strlen(bound);
406 part = 0;
407 state = 0;
408 first = 1;
409 parts = sk_BIO_new_null();
410 *ret = parts;
411 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
412 state = mime_bound_check(linebuf, len, bound, blen);
413 if(state == 1) {
414 first = 1;
415 part++;
416 } else if(state == 2) {
417 sk_BIO_push(parts, bpart);
418 return 1;
419 } else if(part) {
420 /* Strip CR+LF from linebuf */
421 next_eol = strip_eol(linebuf, &len);
422 if(first) {
423 first = 0;
424 if(bpart) sk_BIO_push(parts, bpart);
425 bpart = BIO_new(BIO_s_mem());
426 BIO_set_mem_eof_return(bpart, 0);
427 } else if (eol)
428 BIO_write(bpart, "\r\n", 2);
429 eol = next_eol;
430 if (len)
431 BIO_write(bpart, linebuf, len);
432 }
433 }
434 return 0;
435}
436
437/* This is the big one: parse MIME header lines up to message body */
438
439#define MIME_INVALID 0
440#define MIME_START 1
441#define MIME_TYPE 2
442#define MIME_NAME 3
443#define MIME_VALUE 4
444#define MIME_QUOTE 5
445#define MIME_COMMENT 6
446
447
448static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
449{
450 char *p, *q, c;
451 char *ntmp;
452 char linebuf[MAX_SMLEN];
453 MIME_HEADER *mhdr = NULL;
454 STACK_OF(MIME_HEADER) *headers;
455 int len, state, save_state = 0;
456
457 headers = sk_MIME_HEADER_new(mime_hdr_cmp);
458 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
459 /* If whitespace at line start then continuation line */
460 if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
461 else state = MIME_START;
462 ntmp = NULL;
463 /* Go through all characters */
464 for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
465
466 /* State machine to handle MIME headers
467 * if this looks horrible that's because it *is*
468 */
469
470 switch(state) {
471 case MIME_START:
472 if(c == ':') {
473 state = MIME_TYPE;
474 *p = 0;
475 ntmp = strip_ends(q);
476 q = p + 1;
477 }
478 break;
479
480 case MIME_TYPE:
481 if(c == ';') {
482 mime_debug("Found End Value\n");
483 *p = 0;
484 mhdr = mime_hdr_new(ntmp, strip_ends(q));
485 sk_MIME_HEADER_push(headers, mhdr);
486 ntmp = NULL;
487 q = p + 1;
488 state = MIME_NAME;
489 } else if(c == '(') {
490 save_state = state;
491 state = MIME_COMMENT;
492 }
493 break;
494
495 case MIME_COMMENT:
496 if(c == ')') {
497 state = save_state;
498 }
499 break;
500
501 case MIME_NAME:
502 if(c == '=') {
503 state = MIME_VALUE;
504 *p = 0;
505 ntmp = strip_ends(q);
506 q = p + 1;
507 }
508 break ;
509
510 case MIME_VALUE:
511 if(c == ';') {
512 state = MIME_NAME;
513 *p = 0;
514 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
515 ntmp = NULL;
516 q = p + 1;
517 } else if (c == '"') {
518 mime_debug("Found Quote\n");
519 state = MIME_QUOTE;
520 } else if(c == '(') {
521 save_state = state;
522 state = MIME_COMMENT;
523 }
524 break;
525
526 case MIME_QUOTE:
527 if(c == '"') {
528 mime_debug("Found Match Quote\n");
529 state = MIME_VALUE;
530 }
531 break;
532 }
533 }
534
535 if(state == MIME_TYPE) {
536 mhdr = mime_hdr_new(ntmp, strip_ends(q));
537 sk_MIME_HEADER_push(headers, mhdr);
538 } else if(state == MIME_VALUE)
539 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
540 if(p == linebuf) break; /* Blank line means end of headers */
541}
542
543return headers;
544
545}
546
547static char *strip_ends(char *name)
548{
549 return strip_end(strip_start(name));
550}
551
552/* Strip a parameter of whitespace from start of param */
553static char *strip_start(char *name)
554{
555 char *p, c;
556 /* Look for first non white space or quote */
557 for(p = name; (c = *p) ;p++) {
558 if(c == '"') {
559 /* Next char is start of string if non null */
560 if(p[1]) return p + 1;
561 /* Else null string */
562 return NULL;
563 }
564 if(!isspace((unsigned char)c)) return p;
565 }
566 return NULL;
567}
568
569/* As above but strip from end of string : maybe should handle brackets? */
570static char *strip_end(char *name)
571{
572 char *p, c;
573 if(!name) return NULL;
574 /* Look for first non white space or quote */
575 for(p = name + strlen(name) - 1; p >= name ;p--) {
576 c = *p;
577 if(c == '"') {
578 if(p - 1 == name) return NULL;
579 *p = 0;
580 return name;
581 }
582 if(isspace((unsigned char)c)) *p = 0;
583 else return name;
584 }
585 return NULL;
586}
587
588static MIME_HEADER *mime_hdr_new(char *name, char *value)
589{
590 MIME_HEADER *mhdr;
591 char *tmpname, *tmpval, *p;
592 int c;
593 if(name) {
594 if(!(tmpname = BUF_strdup(name))) return NULL;
595 for(p = tmpname ; *p; p++) {
596 c = *p;
597 if(isupper(c)) {
598 c = tolower(c);
599 *p = c;
600 }
601 }
602 } else tmpname = NULL;
603 if(value) {
604 if(!(tmpval = BUF_strdup(value))) return NULL;
605 for(p = tmpval ; *p; p++) {
606 c = *p;
607 if(isupper(c)) {
608 c = tolower(c);
609 *p = c;
610 }
611 }
612 } else tmpval = NULL;
613 mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
614 if(!mhdr) return NULL;
615 mhdr->name = tmpname;
616 mhdr->value = tmpval;
617 if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
618 return mhdr;
619}
620
621static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
622{
623 char *tmpname, *tmpval, *p;
624 int c;
625 MIME_PARAM *mparam;
626 if(name) {
627 tmpname = BUF_strdup(name);
628 if(!tmpname) return 0;
629 for(p = tmpname ; *p; p++) {
630 c = *p;
631 if(isupper(c)) {
632 c = tolower(c);
633 *p = c;
634 }
635 }
636 } else tmpname = NULL;
637 if(value) {
638 tmpval = BUF_strdup(value);
639 if(!tmpval) return 0;
640 } else tmpval = NULL;
641 /* Parameter values are case sensitive so leave as is */
642 mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
643 if(!mparam) return 0;
644 mparam->param_name = tmpname;
645 mparam->param_value = tmpval;
646 sk_MIME_PARAM_push(mhdr->params, mparam);
647 return 1;
648}
649
650static int mime_hdr_cmp(const MIME_HEADER * const *a,
651 const MIME_HEADER * const *b)
652{
653 return(strcmp((*a)->name, (*b)->name));
654}
655
656static int mime_param_cmp(const MIME_PARAM * const *a,
657 const MIME_PARAM * const *b)
658{
659 return(strcmp((*a)->param_name, (*b)->param_name));
660}
661
662/* Find a header with a given name (if possible) */
663
664static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
665{
666 MIME_HEADER htmp;
667 int idx;
668 htmp.name = name;
669 idx = sk_MIME_HEADER_find(hdrs, &htmp);
670 if(idx < 0) return NULL;
671 return sk_MIME_HEADER_value(hdrs, idx);
672}
673
674static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
675{
676 MIME_PARAM param;
677 int idx;
678 param.param_name = name;
679 idx = sk_MIME_PARAM_find(hdr->params, &param);
680 if(idx < 0) return NULL;
681 return sk_MIME_PARAM_value(hdr->params, idx);
682}
683
684static void mime_hdr_free(MIME_HEADER *hdr)
685{
686 if(hdr->name) OPENSSL_free(hdr->name);
687 if(hdr->value) OPENSSL_free(hdr->value);
688 if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
689 OPENSSL_free(hdr);
690}
691
692static void mime_param_free(MIME_PARAM *param)
693{
694 if(param->param_name) OPENSSL_free(param->param_name);
695 if(param->param_value) OPENSSL_free(param->param_value);
696 OPENSSL_free(param);
697}
698
699/* Check for a multipart boundary. Returns:
700 * 0 : no boundary
701 * 1 : part boundary
702 * 2 : final boundary
703 */
704static int mime_bound_check(char *line, int linelen, char *bound, int blen)
705{
706 if(linelen == -1) linelen = strlen(line);
707 if(blen == -1) blen = strlen(bound);
708 /* Quickly eliminate if line length too short */
709 if(blen + 2 > linelen) return 0;
710 /* Check for part boundary */
711 if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
712 if(!strncmp(line + blen + 2, "--", 2)) return 2;
713 else return 1;
714 }
715 return 0;
716}
717
718static int strip_eol(char *linebuf, int *plen)
719 {
720 int len = *plen;
721 char *p, c;
722 int is_eol = 0;
723 p = linebuf + len - 1;
724 for (p = linebuf + len - 1; len > 0; len--, p--)
725 {
726 c = *p;
727 if (c == '\n')
728 is_eol = 1;
729 else if (c != '\r')
730 break;
731 }
732 *plen = len;
733 return is_eol;
734 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c
deleted file mode 100644
index 99a0d63f38..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_smime.c
+++ /dev/null
@@ -1,469 +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 *tmpin, *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 /* Performance optimization: if the content is a memory BIO then
232 * store its contents in a temporary read only memory BIO. This
233 * avoids potentially large numbers of slow copies of data which will
234 * occur when reading from a read write memory BIO when signatures
235 * are calculated.
236 */
237
238 if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM))
239 {
240 char *ptr;
241 long len;
242 len = BIO_get_mem_data(indata, &ptr);
243 tmpin = BIO_new_mem_buf(ptr, len);
244 if (tmpin == NULL)
245 {
246 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
247 return 0;
248 }
249 }
250 else
251 tmpin = indata;
252
253
254 p7bio=PKCS7_dataInit(p7,tmpin);
255
256 if(flags & PKCS7_TEXT) {
257 if(!(tmpout = BIO_new(BIO_s_mem()))) {
258 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
259 goto err;
260 }
261 } else tmpout = out;
262
263 /* We now have to 'read' from p7bio to calculate digests etc. */
264 for (;;)
265 {
266 i=BIO_read(p7bio,buf,sizeof(buf));
267 if (i <= 0) break;
268 if (tmpout) BIO_write(tmpout, buf, i);
269 }
270
271 if(flags & PKCS7_TEXT) {
272 if(!SMIME_text(tmpout, out)) {
273 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR);
274 BIO_free(tmpout);
275 goto err;
276 }
277 BIO_free(tmpout);
278 }
279
280 /* Now Verify All Signatures */
281 if (!(flags & PKCS7_NOSIGS))
282 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
283 {
284 si=sk_PKCS7_SIGNER_INFO_value(sinfos,i);
285 signer = sk_X509_value (signers, i);
286 j=PKCS7_signatureVerify(p7bio,p7,si, signer);
287 if (j <= 0) {
288 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE);
289 goto err;
290 }
291 }
292
293 ret = 1;
294
295 err:
296
297 if (tmpin == indata)
298 {
299 if (indata) BIO_pop(p7bio);
300 }
301 BIO_free_all(p7bio);
302
303 sk_X509_free(signers);
304
305 return ret;
306}
307
308STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
309{
310 STACK_OF(X509) *signers;
311 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
312 PKCS7_SIGNER_INFO *si;
313 PKCS7_ISSUER_AND_SERIAL *ias;
314 X509 *signer;
315 int i;
316
317 if(!p7) {
318 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER);
319 return NULL;
320 }
321
322 if(!PKCS7_type_is_signed(p7)) {
323 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE);
324 return NULL;
325 }
326
327 /* Collect all the signers together */
328
329 sinfos = PKCS7_get_signer_info(p7);
330
331 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
332 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
333 return 0;
334 }
335
336 if(!(signers = sk_X509_new_null())) {
337 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE);
338 return NULL;
339 }
340
341 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
342 {
343 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
344 ias = si->issuer_and_serial;
345 signer = NULL;
346 /* If any certificates passed they take priority */
347 if (certs) signer = X509_find_by_issuer_and_serial (certs,
348 ias->issuer, ias->serial);
349 if (!signer && !(flags & PKCS7_NOINTERN)
350 && p7->d.sign->cert) signer =
351 X509_find_by_issuer_and_serial (p7->d.sign->cert,
352 ias->issuer, ias->serial);
353 if (!signer) {
354 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
355 sk_X509_free(signers);
356 return 0;
357 }
358
359 sk_X509_push(signers, signer);
360 }
361 return signers;
362}
363
364
365/* Build a complete PKCS#7 enveloped data */
366
367PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
368 int flags)
369{
370 PKCS7 *p7;
371 BIO *p7bio = NULL;
372 int i;
373 X509 *x509;
374 if(!(p7 = PKCS7_new())) {
375 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
376 return NULL;
377 }
378
379 PKCS7_set_type(p7, NID_pkcs7_enveloped);
380 if(!PKCS7_set_cipher(p7, cipher)) {
381 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
382 goto err;
383 }
384
385 for(i = 0; i < sk_X509_num(certs); i++) {
386 x509 = sk_X509_value(certs, i);
387 if(!PKCS7_add_recipient(p7, x509)) {
388 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
389 PKCS7_R_ERROR_ADDING_RECIPIENT);
390 goto err;
391 }
392 }
393
394 if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
395 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
396 goto err;
397 }
398
399 SMIME_crlf_copy(in, p7bio, flags);
400
401 BIO_flush(p7bio);
402
403 if (!PKCS7_dataFinal(p7,p7bio)) {
404 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
405 goto err;
406 }
407 BIO_free_all(p7bio);
408
409 return p7;
410
411 err:
412
413 BIO_free(p7bio);
414 PKCS7_free(p7);
415 return NULL;
416
417}
418
419int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
420{
421 BIO *tmpmem;
422 int ret, i;
423 char buf[4096];
424
425 if(!p7) {
426 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER);
427 return 0;
428 }
429
430 if(!PKCS7_type_is_enveloped(p7)) {
431 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE);
432 return 0;
433 }
434
435 if(!X509_check_private_key(cert, pkey)) {
436 PKCS7err(PKCS7_F_PKCS7_DECRYPT,
437 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
438 return 0;
439 }
440
441 if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
442 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
443 return 0;
444 }
445
446 if (flags & PKCS7_TEXT) {
447 BIO *tmpbuf, *bread;
448 /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
449 if(!(tmpbuf = BIO_new(BIO_f_buffer()))) {
450 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
451 return 0;
452 }
453 if(!(bread = BIO_push(tmpbuf, tmpmem))) {
454 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
455 return 0;
456 }
457 ret = SMIME_text(bread, data);
458 BIO_free_all(bread);
459 return ret;
460 } else {
461 for(;;) {
462 i = BIO_read(tmpmem, buf, sizeof(buf));
463 if(i <= 0) break;
464 BIO_write(data, buf, i);
465 }
466 BIO_free_all(tmpmem);
467 return 1;
468 }
469}
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 19894c80a4..0000000000
--- a/src/lib/libcrypto/pkcs7/pkcs7err.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/* crypto/pkcs7/pkcs7err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2005 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
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
70
71static ERR_STRING_DATA PKCS7_str_functs[]=
72 {
73{ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"},
74{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"},
75{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), "PKCS7_add_attrib_smimecap"},
76{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"},
77{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"},
78{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"},
79{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"},
80{ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"},
81{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"},
82{ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"},
83{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"},
84{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"},
85{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
86{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
87{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"},
88{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"},
89{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"},
90{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"},
91{ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"},
92{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"},
93{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"},
94{ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"},
95{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"},
96{ERR_FUNC(PKCS7_F_SMIME_TEXT), "SMIME_text"},
97{0,NULL}
98 };
99
100static ERR_STRING_DATA PKCS7_str_reasons[]=
101 {
102{ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
103{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
104{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"},
105{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"},
106{ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"},
107{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"},
108{ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"},
109{ERR_REASON(PKCS7_R_DIGEST_FAILURE) ,"digest failure"},
110{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"},
111{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
112{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) ,"invalid mime type"},
113{ERR_REASON(PKCS7_R_INVALID_NULL_POINTER),"invalid null pointer"},
114{ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE),"mime no content type"},
115{ERR_REASON(PKCS7_R_MIME_PARSE_ERROR) ,"mime parse error"},
116{ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR),"mime sig parse error"},
117{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"},
118{ERR_REASON(PKCS7_R_NO_CONTENT) ,"no content"},
119{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) ,"no content type"},
120{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
121{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
122{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},
123{ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA),"no signatures on data"},
124{ERR_REASON(PKCS7_R_NO_SIGNERS) ,"no signers"},
125{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
126{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"},
127{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
128{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"},
129{ERR_REASON(PKCS7_R_PKCS7_DATASIGN) ,"pkcs7 datasign"},
130{ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR) ,"pkcs7 parse error"},
131{ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR),"pkcs7 sig parse error"},
132{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
133{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) ,"signature failure"},
134{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
135{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
136{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) ,"smime text error"},
137{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"},
138{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO),"unable to find mem bio"},
139{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST),"unable to find message digest"},
140{ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE) ,"unknown digest type"},
141{ERR_REASON(PKCS7_R_UNKNOWN_OPERATION) ,"unknown operation"},
142{ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE),"unsupported cipher type"},
143{ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
144{ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE) ,"wrong content type"},
145{ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE) ,"wrong pkcs7 type"},
146{0,NULL}
147 };
148
149#endif
150
151void ERR_load_PKCS7_strings(void)
152 {
153 static int init=1;
154
155 if (init)
156 {
157 init=0;
158#ifndef OPENSSL_NO_ERR
159 ERR_load_strings(0,PKCS7_str_functs);
160 ERR_load_strings(0,PKCS7_str_reasons);
161#endif
162
163 }
164 }