zxid
view release on metacpan or search on metacpan
smime-enc.c view on Meta::CPAN
message to be signed
--sig42
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Clear Signed Message
MIAGCSqGSIb3DQEHA6CAMIIIZQIBADGCATcwggEzAgEAMIGbMIGVMQswCQYDVQQG
EwJQVDEPMA0GA1UEBxMGTGlzYm9hMRcwFQYDVQQKEw5OZXVyb25pbywgTGRhLjEZ
G0DXAj0zd/4AAAAA==
--sig42--
*/
/* Called by: smime_clear_sign */
char* /* returns smime encoded clear signed blob, or NULL if error */
clear_sign(X509* x509, EVP_PKEY* pkey, const char* mime_entity)
{
char* b;
char* b64;
BIO* wbio = 0;
int n;
LOG_PRINT("clear sig, canon entity...");
if (!(mime_entity = mime_canon(mime_entity))) goto err;
LOG_PRINT("clear sig, entity canoned. Now sig engine");
/* Run crypto stuff over the mime_entity */
if (!(wbio = smime_sign_engine(x509, pkey, mime_entity, 1))) goto err;
LOG_PRINT("clear sig: signed, now get data");
n = BIO_get_mem_data(wbio,&b64);
LOG_PRINT("clear sig: cut pem markers...");
if (!(b64 = cut_pem_markers_off(b64, n, "PKCS7"))) goto err;
/* Wrap up the result in multipart/signed object */
if (!(b = smime_mk_multipart_signed(mime_entity, b64))) goto err;
LOG_PRINT("clear sig: done. free bio");
BIO_free_all(wbio); /* this will also free b64 because b64 hangs from bio */
return b;
err:
if (wbio) BIO_free_all(wbio);
return NULL;
}
/* Called by: main x2 */
char*
smime_clear_sign(const char* privkey,
const char* password,
const char* mime_entity)
{
char* b = NULL;
X509* x509 = NULL;
EVP_PKEY* pkey = NULL;
/* Get key and certificate (why do we need both?) */
if (!(pkey = open_private_key(privkey, password))) goto err;
if (!(x509 = extract_certificate(privkey))) goto err;
if (!(b = clear_sign(x509, pkey, mime_entity))) goto err;
err:
if (pkey) EVP_PKEY_free(pkey);
if (x509) X509_free(x509);
return b;
}
/* Sign a mime entity, such as produced by mime_mk_multipart(). Signature
* and entity are output as one base64 blob so the entity is not trivially
* visible. */
/*
MIME-Version: 1.0
Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7m"
Content-Description: S/MIME Signed Message
MIAGCSqGSIb3DQEHA6CAMIIIZQIBADGCATcwggEzAgEAMIGbMIGVMQswCQYDVQQG
EwJQVDEPMA0GA1UEBxMGTGlzYm9hMRcwFQYDVQQKEw5OZXVyb25pbywgTGRhLjEZ
G0DXAj0zd/4AAAAA==
*/
/* Called by: smime_sign */
char* /* returns smime blob, NULL if error */
sign(X509* x509, EVP_PKEY* pkey, const char* mime_entity)
{
char* b;
char* b64;
BIO* wbio;
int n;
mime_entity = mime_canon(mime_entity);
/* Run crypto stuff over the mime_entity */
if (!(wbio = smime_sign_engine(x509, pkey, mime_entity, 0))) goto err;
n = BIO_get_mem_data(wbio,&b64);
if (!(b64 = cut_pem_markers_off(b64, n, "PKCS7"))) goto err;
/* Add headers */
if (!(b = strdup("Content-type: application/x-pkcs7-mime; name=\"smime.p7m\"" CRLF
"Content-transfer-encoding: base64" CRLF
"Content-Disposition: attachment; filename=\"smime.p7m\"" CRLF
CRLF))) GOTO_ERR("no memory?");
if (!(b = concat(b, b64))) GOTO_ERR("no memory?");
BIO_free_all(wbio); /* also frees b64 */
return b;
err:
if (wbio) BIO_free_all(wbio);
return NULL;
}
/* Called by: main */
char*
smime_sign(const char* privkey, const char* password, const char* mime_entity)
{
char* b = NULL;
X509* x509 = NULL;
EVP_PKEY* pkey = NULL;
/* Get key and certificate (why do we need both?) */
if (!(pkey = open_private_key(privkey, password))) goto err;
if (!(x509 = extract_certificate(privkey))) goto err;
if (!(b = sign(x509, pkey, mime_entity))) goto err;
err:
if (pkey) EVP_PKEY_free(pkey);
if (x509) X509_free(x509);
return b;
}
/* Encrypt a mime entity such as produced by smime_clear_sign(). */
/*
MIME-Version: 1.0
Content-Type: application/x-pkcs7-mime; name="smime.p7m"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7m"
Content-Description: S/MIME Encrypted Message
MIAGCSqGSIb3DQEHA6CAMIIIZQIBADGCATcwggEzAgEAMIGbMIGVMQswCQYDVQQG
EwJQVDEPMA0GA1UEBxMGTGlzYm9hMRcwFQYDVQQKEw5OZXVyb25pbywgTGRhLjEZ
G0DXAj0zd/4AAAAA==
*/
/* Called by: smime_encrypt */
char*
encrypt1(X509* x509, const char* mime_entity)
{
time_t t;
char* b;
char* b64;
int i, n;
char buf[4096];
BIO* p7bio = NULL;
BIO* rbio = NULL;
BIO* wbio = NULL;
PKCS7* p7 = NULL;;
t = time(NULL);
RAND_seed(&t,sizeof(t));
#ifdef WINDOWS
RAND_screen(); /* Loading video display memory into random state */
#endif
LOG_PRINT3("encrypt1", x509, mime_entity);
/* Set up BIOs and PKCS7 machinery */
if (!(rbio = set_read_BIO_from_buf(mime_entity, -1))) goto err;
if (!(p7=PKCS7_new())) GOTO_ERR("no memory?");
PKCS7_set_type(p7,NID_pkcs7_enveloped);
#if 1
if (!PKCS7_set_cipher(p7,EVP_des_ede3_cbc()))
GOTO_ERR("PKCS7_set_cipher des-ede3-cbc");
#else
/* SECURITY CAVEAT: weak cipher by default */
if (!PKCS7_set_cipher(p7,EVP_rc2_40_cbc()))
GOTO_ERR("PKCS7_set_cipher rc2-40-cbc");
#endif
( run in 2.789 seconds using v1.01-cache-2.11-cpan-5c0b1e786e0 )