~ubuntu-branches/ubuntu/oneiric/openssl/oneiric

« back to all changes in this revision

Viewing changes to crypto/pkcs7/pk7_smime.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-05-01 23:51:53 UTC
  • mfrom: (11.1.20 sid)
  • Revision ID: james.westby@ubuntu.com-20110501235153-bjcxitndquaezb68
Tags: 1.0.0d-2ubuntu1
* Resynchronise with Debian (LP: #675566).  Remaining changes:
  - debian/libssl1.0.0.postinst:
    + Display a system restart required notification bubble on libssl1.0.0
      upgrade.
    + Use a different priority for libssl1.0.0/restart-services depending
      on whether a desktop, or server dist-upgrade is being performed.
  - debian/{libssl1.0.0-udeb.dirs, control, rules}: Create
    libssl1.0.0-udeb, for the benefit of wget-udeb (no wget-udeb package
    in Debian).
  - debian/{libcrypto1.0.0-udeb.dirs, libssl1.0.0.dirs, libssl1.0.0.files,
    rules}: Move runtime libraries to /lib, for the benefit of
    wpasupplicant.
  - debian/patches/aesni.patch: Backport Intel AES-NI support, now from
    http://rt.openssl.org/Ticket/Display.html?id=2065 rather than the
    0.9.8 variant.
  - debian/patches/Bsymbolic-functions.patch: Link using
    -Bsymbolic-functions.
  - debian/patches/perlpath-quilt.patch: Don't change perl #! paths under
    .pc.
  - debian/rules:
    + Don't run 'make test' when cross-building.
    + Use host compiler when cross-building.  Patch from Neil Williams.
    + Don't build for processors no longer supported: i486, i586 (on
      i386), v8 (on sparc).
    + Fix Makefile to properly clean up libs/ dirs in clean target.
    + Replace duplicate files in the doc directory with symlinks.
* Update architectures affected by Bsymbolic-functions.patch.
* Drop debian/patches/no-sslv2.patch; Debian now adds the 'no-ssl2'
  configure option, which compiles out SSLv2 support entirely, so this is
  no longer needed.
* Drop openssl-doc in favour of the libssl-doc package introduced by
  Debian.  Add Conflicts/Replaces until the next LTS release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
#include <openssl/x509.h>
64
64
#include <openssl/x509v3.h>
65
65
 
 
66
static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
 
67
 
66
68
PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
67
69
                  BIO *data, int flags)
68
70
{
69
 
        PKCS7 *p7 = NULL;
70
 
        PKCS7_SIGNER_INFO *si;
71
 
        BIO *p7bio = NULL;
 
71
        PKCS7 *p7;
 
72
        int i;
 
73
 
 
74
        if(!(p7 = PKCS7_new()))
 
75
                {
 
76
                PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
 
77
                return NULL;
 
78
                }
 
79
 
 
80
        if (!PKCS7_set_type(p7, NID_pkcs7_signed))
 
81
                goto err;
 
82
 
 
83
        if (!PKCS7_content_new(p7, NID_pkcs7_data))
 
84
                goto err;
 
85
 
 
86
        if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
 
87
                {
 
88
                PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
 
89
                goto err;
 
90
                }
 
91
 
 
92
        if(!(flags & PKCS7_NOCERTS))
 
93
                {
 
94
                for(i = 0; i < sk_X509_num(certs); i++)
 
95
                        {
 
96
                        if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
 
97
                                goto err;
 
98
                        }
 
99
                }
 
100
 
 
101
        if(flags & PKCS7_DETACHED)
 
102
                PKCS7_set_detached(p7, 1);
 
103
 
 
104
        if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
 
105
                return p7;
 
106
 
 
107
        if (PKCS7_final(p7, data, flags))
 
108
                return p7;
 
109
 
 
110
        err:
 
111
        PKCS7_free(p7);
 
112
        return NULL;
 
113
}
 
114
 
 
115
int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
 
116
        {
 
117
        BIO *p7bio;
 
118
        int ret = 0;
 
119
        if (!(p7bio = PKCS7_dataInit(p7, NULL)))
 
120
                {
 
121
                PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
 
122
                return 0;
 
123
                }
 
124
 
 
125
        SMIME_crlf_copy(data, p7bio, flags);
 
126
 
 
127
        (void)BIO_flush(p7bio);
 
128
 
 
129
 
 
130
        if (!PKCS7_dataFinal(p7,p7bio))
 
131
                {
 
132
                PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
 
133
                goto err;
 
134
                }
 
135
 
 
136
        ret = 1;
 
137
 
 
138
        err:
 
139
        BIO_free_all(p7bio);
 
140
 
 
141
        return ret;
 
142
 
 
143
        }
 
144
 
 
145
/* Check to see if a cipher exists and if so add S/MIME capabilities */
 
146
 
 
147
static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
 
148
        {
 
149
        if (EVP_get_cipherbynid(nid))
 
150
                return PKCS7_simple_smimecap(sk, nid, arg);
 
151
        return 1;
 
152
        }
 
153
 
 
154
static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
 
155
        {
 
156
        if (EVP_get_digestbynid(nid))
 
157
                return PKCS7_simple_smimecap(sk, nid, arg);
 
158
        return 1;
 
159
        }
 
160
 
 
161
PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
 
162
                                        EVP_PKEY *pkey, const EVP_MD *md,
 
163
                                        int flags)
 
164
        {
 
165
        PKCS7_SIGNER_INFO *si = NULL;
72
166
        STACK_OF(X509_ALGOR) *smcap = NULL;
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);
 
167
        if(!X509_check_private_key(signcert, pkey))
 
168
                {
 
169
                PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
 
170
                        PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
77
171
                return NULL;
78
 
        }
 
172
                }
79
173
 
80
 
        if(!(p7 = PKCS7_new())) {
81
 
                PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
 
174
        if (!(si = PKCS7_add_signature(p7,signcert,pkey, md)))
 
175
                {
 
176
                PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
 
177
                                PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
82
178
                return NULL;
83
 
        }
84
 
 
85
 
        if (!PKCS7_set_type(p7, NID_pkcs7_signed))
86
 
                goto err;
87
 
 
88
 
        if (!PKCS7_content_new(p7, NID_pkcs7_data))
89
 
                goto err;
90
 
 
91
 
        if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) {
92
 
                PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
93
 
                goto err;
94
 
        }
95
 
 
96
 
        if(!(flags & PKCS7_NOCERTS)) {
 
179
                }
 
180
 
 
181
        if(!(flags & PKCS7_NOCERTS))
 
182
                {
97
183
                if (!PKCS7_add_certificate(p7, signcert))
98
184
                        goto err;
99
 
                if(certs) for(i = 0; i < sk_X509_num(certs); i++)
100
 
                        if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
101
 
                                goto err;
102
 
        }
 
185
                }
103
186
 
104
 
        if(!(flags & PKCS7_NOATTR)) {
105
 
                if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
106
 
                                V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)))
 
187
        if(!(flags & PKCS7_NOATTR))
 
188
                {
 
189
                if (!PKCS7_add_attrib_content_type(si, NULL))
107
190
                        goto err;
108
191
                /* Add SMIMECapabilities */
109
192
                if(!(flags & PKCS7_NOSMIMECAP))
110
 
                {
111
 
                if(!(smcap = sk_X509_ALGOR_new_null())) {
112
 
                        PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
113
 
                        goto err;
 
193
                        {
 
194
                        if(!(smcap = sk_X509_ALGOR_new_null()))
 
195
                                {
 
196
                                PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
 
197
                                        ERR_R_MALLOC_FAILURE);
 
198
                                goto err;
 
199
                                }
 
200
                        if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
 
201
                        || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
 
202
                        || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
 
203
                                || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
 
204
                                || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
 
205
                        || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
 
206
                                || !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
 
207
                                || !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
 
208
                                || !add_cipher_smcap(smcap, NID_des_cbc, -1)
 
209
                                || !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
 
210
                                || !PKCS7_add_attrib_smimecap (si, smcap))
 
211
                                goto err;
 
212
                        sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
 
213
                        smcap = NULL;
 
214
                        }
 
215
                if (flags & PKCS7_REUSE_DIGEST)
 
216
                        {
 
217
                        if (!pkcs7_copy_existing_digest(p7, si))
 
218
                                goto err;
 
219
                        if (!(flags & PKCS7_PARTIAL) &&
 
220
                                        !PKCS7_SIGNER_INFO_sign(si))
 
221
                                goto err;
 
222
                        }
114
223
                }
115
 
#ifndef OPENSSL_NO_DES
116
 
                if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1))
117
 
                        goto err;
118
 
#endif
119
 
#ifndef OPENSSL_NO_RC2
120
 
                if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128))
121
 
                        goto err;
122
 
                if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64))
123
 
                        goto err;
124
 
#endif
125
 
#ifndef OPENSSL_NO_DES
126
 
                if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1))
127
 
                        goto err;
128
 
#endif
129
 
#ifndef OPENSSL_NO_RC2
130
 
                if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40))
131
 
                        goto err;
132
 
#endif
133
 
                if (!PKCS7_add_attrib_smimecap (si, smcap))
134
 
                        goto err;
 
224
        return si;
 
225
        err:
 
226
        if (smcap)
135
227
                sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
136
 
                smcap = NULL;
 
228
        return NULL;
 
229
        }
 
230
 
 
231
/* Search for a digest matching SignerInfo digest type and if found
 
232
 * copy across.
 
233
 */
 
234
 
 
235
static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
 
236
        {
 
237
        int i;
 
238
        STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
 
239
        PKCS7_SIGNER_INFO *sitmp;
 
240
        ASN1_OCTET_STRING *osdig = NULL;
 
241
        sinfos = PKCS7_get_signer_info(p7);
 
242
        for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
 
243
                {
 
244
                sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
 
245
                if (si == sitmp)
 
246
                        break;
 
247
                if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
 
248
                        continue;
 
249
                if (!OBJ_cmp(si->digest_alg->algorithm,
 
250
                                sitmp->digest_alg->algorithm))
 
251
                        {
 
252
                        osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
 
253
                        break;
 
254
                        }
 
255
 
137
256
                }
138
 
        }
139
 
 
140
 
        if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1);
141
 
 
142
 
        if (flags & PKCS7_STREAM)
143
 
                return p7;
144
 
 
145
 
 
146
 
        if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
147
 
                PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
148
 
                goto err;
149
 
        }
150
 
 
151
 
        SMIME_crlf_copy(data, p7bio, flags);
152
 
 
153
 
 
154
 
        if (!PKCS7_dataFinal(p7,p7bio)) {
155
 
                PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN);
156
 
                goto err;
157
 
        }
158
 
 
159
 
        BIO_free_all(p7bio);
160
 
        return p7;
161
 
err:
162
 
        sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
163
 
        BIO_free_all(p7bio);
164
 
        PKCS7_free(p7);
165
 
        return NULL;
166
 
}
 
257
 
 
258
        if (osdig)
 
259
                return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
 
260
 
 
261
        PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
 
262
                        PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
 
263
        return 0;
 
264
        }
167
265
 
168
266
int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
169
267
                                        BIO *indata, BIO *out, int flags)
354
452
 
355
453
        if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
356
454
                PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
357
 
                return NULL;
 
455
                return 0;
358
456
        }
359
457
 
360
458
        if(!(signers = sk_X509_new_null())) {
377
475
            if (!signer) {
378
476
                        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
379
477
                        sk_X509_free(signers);
380
 
                        return NULL;
 
478
                        return 0;
381
479
            }
382
480
 
383
481
            if (!sk_X509_push(signers, signer)) {
384
 
                        sk_X509_free(signers);
385
 
                        return NULL;
 
482
                sk_X509_free(signers);
 
483
                return NULL;
386
484
            }
387
485
        }
388
486
        return signers;
405
503
 
406
504
        if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
407
505
                goto err;
408
 
        if(!PKCS7_set_cipher(p7, cipher)) {
 
506
        if (!PKCS7_set_cipher(p7, cipher)) {
409
507
                PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
410
508
                goto err;
411
509
        }
419
517
                }
420
518
        }
421
519
 
422
 
        if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
423
 
                PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
424
 
                goto err;
425
 
        }
426
 
 
427
 
        SMIME_crlf_copy(in, p7bio, flags);
428
 
 
429
 
        (void)BIO_flush(p7bio);
430
 
 
431
 
        if (!PKCS7_dataFinal(p7,p7bio)) {
432
 
                PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
433
 
                goto err;
434
 
        }
435
 
        BIO_free_all(p7bio);
436
 
 
437
 
        return p7;
 
520
        if (flags & PKCS7_STREAM)
 
521
                return p7;
 
522
 
 
523
        if (PKCS7_final(p7, in, flags))
 
524
                return p7;
438
525
 
439
526
        err:
440
527