OLD | NEW |
1 /* pk7_smime.c */ | 1 /* pk7_smime.c */ |
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 * project. | 3 * project. |
4 */ | 4 */ |
5 /* ==================================================================== | 5 /* ==================================================================== |
6 * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 * | 56 * |
57 */ | 57 */ |
58 | 58 |
59 /* Simple PKCS#7 processing functions */ | 59 /* Simple PKCS#7 processing functions */ |
60 | 60 |
61 #include <stdio.h> | 61 #include <stdio.h> |
62 #include "cryptlib.h" | 62 #include "cryptlib.h" |
63 #include <openssl/x509.h> | 63 #include <openssl/x509.h> |
64 #include <openssl/x509v3.h> | 64 #include <openssl/x509v3.h> |
65 | 65 |
| 66 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); |
| 67 |
66 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, | 68 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, |
67 BIO *data, int flags) | 69 BIO *data, int flags) |
68 { | 70 { |
69 » PKCS7 *p7 = NULL; | 71 » PKCS7 *p7; |
70 » PKCS7_SIGNER_INFO *si; | |
71 » BIO *p7bio = NULL; | |
72 » STACK_OF(X509_ALGOR) *smcap = NULL; | |
73 int i; | 72 int i; |
74 | 73 |
75 » if(!X509_check_private_key(signcert, pkey)) { | 74 » if(!(p7 = PKCS7_new())) |
76 » » PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_C
ERTIFICATE); | 75 » » { |
77 return NULL; | |
78 » } | |
79 | |
80 » if(!(p7 = PKCS7_new())) { | |
81 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); | 76 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); |
82 return NULL; | 77 return NULL; |
83 » } | 78 » » } |
84 | 79 |
85 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) | 80 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) |
86 goto err; | 81 goto err; |
87 | 82 |
88 if (!PKCS7_content_new(p7, NID_pkcs7_data)) | 83 if (!PKCS7_content_new(p7, NID_pkcs7_data)) |
89 goto err; | 84 goto err; |
90 | 85 |
91 » if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { | 86 » if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) |
92 » » PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); | 87 » » { |
| 88 » » PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR); |
93 goto err; | 89 goto err; |
94 » } | 90 » » } |
95 | 91 |
96 » if(!(flags & PKCS7_NOCERTS)) { | 92 » if(!(flags & PKCS7_NOCERTS)) |
97 » » if (!PKCS7_add_certificate(p7, signcert)) | 93 » » { |
98 » » » goto err; | 94 » » for(i = 0; i < sk_X509_num(certs); i++) |
99 » » if(certs) for(i = 0; i < sk_X509_num(certs); i++) | 95 » » » { |
100 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) | 96 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) |
101 goto err; | 97 goto err; |
102 » } | 98 » » » } |
| 99 » » } |
103 | 100 |
104 » if(!(flags & PKCS7_NOATTR)) { | 101 » if(flags & PKCS7_DETACHED) |
105 » » if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, | 102 » » PKCS7_set_detached(p7, 1); |
106 » » » » V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) | |
107 » » » goto err; | |
108 » » /* Add SMIMECapabilities */ | |
109 » » 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; | |
114 » » } | |
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; | |
135 » » sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); | |
136 » » smcap = NULL; | |
137 » » } | |
138 » } | |
139 | 103 |
140 » if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); | 104 » if (flags & (PKCS7_STREAM|PKCS7_PARTIAL)) |
141 | |
142 » if (flags & PKCS7_STREAM) | |
143 return p7; | 105 return p7; |
144 | 106 |
| 107 if (PKCS7_final(p7, data, flags)) |
| 108 return p7; |
145 | 109 |
146 » if (!(p7bio = PKCS7_dataInit(p7, NULL))) { | 110 » err: |
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); | 111 PKCS7_free(p7); |
165 return NULL; | 112 return NULL; |
166 } | 113 } |
167 | 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; |
| 166 STACK_OF(X509_ALGOR) *smcap = NULL; |
| 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); |
| 171 return NULL; |
| 172 } |
| 173 |
| 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); |
| 178 return NULL; |
| 179 } |
| 180 |
| 181 if(!(flags & PKCS7_NOCERTS)) |
| 182 { |
| 183 if (!PKCS7_add_certificate(p7, signcert)) |
| 184 goto err; |
| 185 } |
| 186 |
| 187 if(!(flags & PKCS7_NOATTR)) |
| 188 { |
| 189 if (!PKCS7_add_attrib_content_type(si, NULL)) |
| 190 goto err; |
| 191 /* Add SMIMECapabilities */ |
| 192 if(!(flags & PKCS7_NOSMIMECAP)) |
| 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 } |
| 223 } |
| 224 return si; |
| 225 err: |
| 226 if (smcap) |
| 227 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); |
| 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 |
| 256 } |
| 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 } |
| 265 |
168 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, | 266 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, |
169 BIO *indata, BIO *out, int flags) | 267 BIO *indata, BIO *out, int flags) |
170 { | 268 { |
171 STACK_OF(X509) *signers; | 269 STACK_OF(X509) *signers; |
172 X509 *signer; | 270 X509 *signer; |
173 STACK_OF(PKCS7_SIGNER_INFO) *sinfos; | 271 STACK_OF(PKCS7_SIGNER_INFO) *sinfos; |
174 PKCS7_SIGNER_INFO *si; | 272 PKCS7_SIGNER_INFO *si; |
175 X509_STORE_CTX cert_ctx; | 273 X509_STORE_CTX cert_ctx; |
176 char buf[4096]; | 274 char buf[4096]; |
177 int i, j=0, k, ret = 0; | 275 int i, j=0, k, ret = 0; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE); | 445 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE); |
348 return NULL; | 446 return NULL; |
349 } | 447 } |
350 | 448 |
351 /* Collect all the signers together */ | 449 /* Collect all the signers together */ |
352 | 450 |
353 sinfos = PKCS7_get_signer_info(p7); | 451 sinfos = PKCS7_get_signer_info(p7); |
354 | 452 |
355 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { | 453 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { |
356 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); | 454 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); |
357 » » return NULL; | 455 » » return 0; |
358 } | 456 } |
359 | 457 |
360 if(!(signers = sk_X509_new_null())) { | 458 if(!(signers = sk_X509_new_null())) { |
361 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE); | 459 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE); |
362 return NULL; | 460 return NULL; |
363 } | 461 } |
364 | 462 |
365 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) | 463 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) |
366 { | 464 { |
367 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); | 465 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); |
368 ias = si->issuer_and_serial; | 466 ias = si->issuer_and_serial; |
369 signer = NULL; | 467 signer = NULL; |
370 /* If any certificates passed they take priority */ | 468 /* If any certificates passed they take priority */ |
371 if (certs) signer = X509_find_by_issuer_and_serial (certs, | 469 if (certs) signer = X509_find_by_issuer_and_serial (certs, |
372 ias->issuer, ias->serial); | 470 ias->issuer, ias->serial); |
373 if (!signer && !(flags & PKCS7_NOINTERN) | 471 if (!signer && !(flags & PKCS7_NOINTERN) |
374 && p7->d.sign->cert) signer = | 472 && p7->d.sign->cert) signer = |
375 X509_find_by_issuer_and_serial (p7->d.sign->cert, | 473 X509_find_by_issuer_and_serial (p7->d.sign->cert, |
376 ias->issuer, ias->serial); | 474 ias->issuer, ias->serial); |
377 if (!signer) { | 475 if (!signer) { |
378 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTI
FICATE_NOT_FOUND); | 476 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTI
FICATE_NOT_FOUND); |
379 sk_X509_free(signers); | 477 sk_X509_free(signers); |
380 » » » return NULL; | 478 » » » return 0; |
381 } | 479 } |
382 | 480 |
383 if (!sk_X509_push(signers, signer)) { | 481 if (!sk_X509_push(signers, signer)) { |
384 » » » sk_X509_free(signers); | 482 » » sk_X509_free(signers); |
385 » » » return NULL; | 483 » » return NULL; |
386 } | 484 } |
387 } | 485 } |
388 return signers; | 486 return signers; |
389 } | 487 } |
390 | 488 |
391 | 489 |
392 /* Build a complete PKCS#7 enveloped data */ | 490 /* Build a complete PKCS#7 enveloped data */ |
393 | 491 |
394 PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, | 492 PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, |
395 int flags) | 493 int flags) |
396 { | 494 { |
397 PKCS7 *p7; | 495 PKCS7 *p7; |
398 BIO *p7bio = NULL; | 496 BIO *p7bio = NULL; |
399 int i; | 497 int i; |
400 X509 *x509; | 498 X509 *x509; |
401 if(!(p7 = PKCS7_new())) { | 499 if(!(p7 = PKCS7_new())) { |
402 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); | 500 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); |
403 return NULL; | 501 return NULL; |
404 } | 502 } |
405 | 503 |
406 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) | 504 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) |
407 goto err; | 505 goto err; |
408 » if(!PKCS7_set_cipher(p7, cipher)) { | 506 » if (!PKCS7_set_cipher(p7, cipher)) { |
409 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); | 507 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); |
410 goto err; | 508 goto err; |
411 } | 509 } |
412 | 510 |
413 for(i = 0; i < sk_X509_num(certs); i++) { | 511 for(i = 0; i < sk_X509_num(certs); i++) { |
414 x509 = sk_X509_value(certs, i); | 512 x509 = sk_X509_value(certs, i); |
415 if(!PKCS7_add_recipient(p7, x509)) { | 513 if(!PKCS7_add_recipient(p7, x509)) { |
416 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, | 514 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, |
417 PKCS7_R_ERROR_ADDING_RECIPIENT); | 515 PKCS7_R_ERROR_ADDING_RECIPIENT); |
418 goto err; | 516 goto err; |
419 } | 517 } |
420 } | 518 } |
421 | 519 |
422 » if(!(p7bio = PKCS7_dataInit(p7, NULL))) { | 520 » if (flags & PKCS7_STREAM) |
423 » » PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); | 521 » » return p7; |
424 » » goto err; | |
425 » } | |
426 | 522 |
427 » SMIME_crlf_copy(in, p7bio, flags); | 523 » if (PKCS7_final(p7, in, flags)) |
428 | 524 » » return p7; |
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; | |
438 | 525 |
439 err: | 526 err: |
440 | 527 |
441 BIO_free_all(p7bio); | 528 BIO_free_all(p7bio); |
442 PKCS7_free(p7); | 529 PKCS7_free(p7); |
443 return NULL; | 530 return NULL; |
444 | 531 |
445 } | 532 } |
446 | 533 |
447 int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) | 534 int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 } else { | 578 } else { |
492 for(;;) { | 579 for(;;) { |
493 i = BIO_read(tmpmem, buf, sizeof(buf)); | 580 i = BIO_read(tmpmem, buf, sizeof(buf)); |
494 if(i <= 0) break; | 581 if(i <= 0) break; |
495 BIO_write(data, buf, i); | 582 BIO_write(data, buf, i); |
496 } | 583 } |
497 BIO_free_all(tmpmem); | 584 BIO_free_all(tmpmem); |
498 return 1; | 585 return 1; |
499 } | 586 } |
500 } | 587 } |
OLD | NEW |