Skip to content

Commit 54286ea

Browse files
add example to generate smime
1 parent 539a282 commit 54286ea

1 file changed

Lines changed: 195 additions & 0 deletions

File tree

pkcs7/smime.c

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/* smime.c
2+
*
3+
* Copyright (C) 2006-2020 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL. (formerly known as CyaSSL)
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
#include <wolfssl/options.h>
23+
#include <wolfssl/wolfcrypt/settings.h>
24+
#include <wolfssl/ssl.h>
25+
#include <wolfssl/wolfcrypt/pkcs7.h>
26+
#include <wolfssl/wolfcrypt/error-crypt.h>
27+
#include <wolfssl/wolfcrypt/logging.h>
28+
29+
30+
#ifdef HAVE_SMIME
31+
32+
/* Create an SMIME bundle, uses steps similar to PKCS7_sign() but this is
33+
* with native PKCS7 API allowing for control over the devID set */
34+
static int Create(byte* smime, int* smimeSz, byte* key, int keySz,
35+
byte* signer, int signerSz, byte* content, int contentSz, int detatched)
36+
{
37+
WOLFSSL_BIO *out, *in;
38+
WOLFSSL_PKCS7* pkcs7Compat;
39+
PKCS7* pkcs7;
40+
int ret = 0;
41+
42+
out = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
43+
in = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
44+
if (out == NULL || in == NULL) {
45+
printf("Failed to create bio's\n");
46+
return -1;
47+
}
48+
49+
pkcs7Compat = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new();
50+
if (pkcs7Compat == NULL) {
51+
ret = MEMORY_E;
52+
}
53+
else {
54+
pkcs7 = &(pkcs7Compat->pkcs7);
55+
56+
/* can change devID here and set signer */
57+
ret = wc_PKCS7_Init(pkcs7, NULL, INVALID_DEVID);
58+
}
59+
60+
if (ret == 0) {
61+
ret = wc_PKCS7_InitWithCert(pkcs7, signer, signerSz);
62+
}
63+
64+
if (ret == 0) {
65+
/* set signer private key, data types, defaults */
66+
pkcs7->privateKey = key;
67+
pkcs7->privateKeySz = keySz;
68+
pkcs7->contentOID = DATA; /* inner content default is DATA */
69+
pkcs7->hashOID = SHA256h; /* default to SHA-256 hash type */
70+
71+
/* type of SMIME */
72+
pkcs7Compat->type = SIGNED_DATA;
73+
74+
/* add additional chain certs if provided */
75+
/* wc_PKCS7_AddCertificate(pkcs7, additionalCert, additionalCertSz); */
76+
77+
/* set detached flag */
78+
if (detatched & PKCS7_DETACHED) {
79+
ret = wc_PKCS7_SetDetached(pkcs7, 1);
80+
}
81+
82+
/* setup content to sign */
83+
if (ret == 0) {
84+
if (wolfSSL_BIO_write(in, content, contentSz) != contentSz) {
85+
ret = -1;
86+
}
87+
}
88+
89+
if (ret == 0) {
90+
if (wolfSSL_SMIME_write_PKCS7(out, (PKCS7*)pkcs7Compat, in,
91+
detatched) != WOLFSSL_SUCCESS) {
92+
printf("SMIME write failed!\n");
93+
ret = -1;
94+
}
95+
}
96+
}
97+
98+
if (ret == 0) {
99+
ret = wolfSSL_BIO_read(out, smime, *smimeSz);
100+
if (ret > 0) {
101+
*smimeSz = ret;
102+
ret = 0;
103+
}
104+
else {
105+
ret = -1;
106+
}
107+
}
108+
109+
wolfSSL_BIO_free(in);
110+
wolfSSL_BIO_free(out);
111+
wolfSSL_PKCS7_free((PKCS7*)pkcs7Compat);
112+
return ret;
113+
}
114+
115+
116+
/* read private key and signer certificate in DER format */
117+
static int ReadKeyAndCert(char* keyFile, char* certFile, byte* key, int* keySz,
118+
byte* cert, int* certSz)
119+
{
120+
int ret;
121+
XFILE f;
122+
123+
f = XFOPEN(keyFile, "rb");
124+
if (f == NULL) {
125+
printf("Error opening file %s\n", keyFile);
126+
return -1;
127+
}
128+
else {
129+
ret = XFREAD(key, 1, *keySz, f);
130+
if (ret >= 0) {
131+
*keySz = ret;
132+
ret = 0;
133+
XFCLOSE(f);
134+
}
135+
}
136+
137+
f = XFOPEN(certFile, "rb");
138+
if (f == NULL) {
139+
printf("Error opening file %s\n", certFile);
140+
return -1;
141+
}
142+
else {
143+
ret = XFREAD(cert, 1, *certSz, f);
144+
if (ret >= 0) {
145+
*certSz = ret;
146+
ret = 0;
147+
XFCLOSE(f);
148+
}
149+
}
150+
151+
return ret;
152+
}
153+
154+
int main(int argc, char** argv)
155+
{
156+
byte key[2048];
157+
int keySz = 2048;
158+
159+
byte cert[2048];
160+
int certSz = 2048;
161+
162+
byte smime[3072];
163+
int smimeSz = 3072;
164+
165+
byte content[] = "Test content to sign";
166+
int contentSz = sizeof(content);
167+
168+
int ret;
169+
int i;
170+
171+
if (argc != 3) {
172+
printf("Use ./smime <der key file> <der cert file>\n");
173+
return -1;
174+
}
175+
176+
ret = ReadKeyAndCert(argv[1], argv[2], key, &keySz, cert, &certSz);
177+
if (ret == 0)
178+
ret = Create(smime, &smimeSz, key, keySz, cert, certSz,
179+
content, contentSz, 0);
180+
if (ret == 0) {
181+
printf("Generated SMIME : ");
182+
for (i = 0; i < smimeSz; i++)
183+
printf("%02X", smime[i]);
184+
printf("\n");
185+
}
186+
187+
return ret;
188+
}
189+
#else
190+
int main()
191+
{
192+
printf("wolfSSL was compiled with out HAVE_SMIME support\n");
193+
return 0;
194+
}
195+
#endif

0 commit comments

Comments
 (0)