/* Copyright (C) 2003 Frédéric Giudicelli (contact_nos@yahoo.com). All rights reserved. This product includes cryptographic software written by Eric Young (eay@cryptsoft.com) This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // MIME.cpp: implementation of the MIME class. // ////////////////////////////////////////////////////////////////////// #include "MIME.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// MIME::MIME() { } MIME::~MIME() { } void MIME::GenerateBoundary(char * boundary, int size) { int i; char c; size--; //Generate boundary marker RAND_pseudo_bytes((unsigned char *)boundary, size); for(i = 0; i < size; i++) { c = boundary[i] & 0xf; if(c < 10) c += '0'; else c += 'A' - 10; boundary[i] = c; } boundary[size+1] = 0; } bool MIME::GenerateMIME(mString & ResultMime, const char *Body, unsigned char *Attach, unsigned int AttachLen, const char *AttachName, const char *AttachType) { char bound[33]; int b64len; char * b64; mString crlfBody; ResultMime = ""; if(!Attach || !AttachLen || !AttachName || !AttachType) { ResultMime = "Content-Type: text/plain; charset=iso-8859-1\r\n\r\n"; ResultMime += Body; return true; } // We have an attachement ! //Convert all \n to \r\n crlfBody = Body; Lf2Crlf(crlfBody); GenerateBoundary(bound, sizeof(bound)); if(!Encoder.Der2Pem((char*)Attach, AttachLen, &b64, &b64len)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ResultMime = "Content-Type: multipart/mixed; boundary=\"----"; ResultMime += bound; ResultMime += "\"\r\n\r\n\r\n"; ResultMime += "------"; ResultMime += bound; ResultMime += "\r\n"; ResultMime += "Content-Type: text/plain\r\n\r\n"; ResultMime += crlfBody; ResultMime += "\r\n------"; ResultMime += bound; ResultMime += "\r\n"; // Headers for attachement ResultMime += "Content-Type: "; ResultMime += AttachType; ResultMime += "; name=\""; ResultMime += AttachName; ResultMime += "\"\r\n"; ResultMime += "Content-Transfer-Encoding: base64\r\n"; ResultMime += "Content-Disposition: attachment; filename=\""; ResultMime += AttachName; ResultMime += "\"\r\n\r\n"; ResultMime += b64; free(b64); ResultMime += "\r\n------"; ResultMime += bound; ResultMime += "--\r\n"; return true; } void MIME::Lf2Crlf(mString & Body) { int pos; //Convert all \n to \r\n pos = 0; do { pos = Body.find("\n", pos); if(pos != -1) { if(pos > 0 && Body[pos-1] != '\r') { Body.replace(pos, 1, "\r\n"); pos+=2; } else { pos++; } } } while(pos != -1); } bool MIME::GenerateSMIME(mString & ResultSmime, const char *Body, const X509 * Signer, const EVP_PKEY * PrivKey, const mVector & Others) { BIO *memin = NULL; PKCS7 * p7; X509 * currCert; mString crlfBody; mString crlfSig; char bound[33]; int derP7len; unsigned char * derP7; unsigned char * p; int b64P7len; char * b64P7; size_t i; STACK_OF(X509) * mOthers; //Convert all \n to \r\n crlfBody = Body; Lf2Crlf(crlfBody); GenerateBoundary(bound, sizeof(bound)); //Generate the signature memin = BIO_new(BIO_s_mem()); if(!memin) { NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); return false; } BIO_printf(memin, "%s", crlfBody.c_str()); BIO_seek(memin, 0); mOthers = SKM_sk_new_null(X509); if(!mOthers) { BIO_free_all(memin); NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); return false; } for(i=0; i