Hi All:
While taking a look at RFC5272 and other things, I got to playing with the CMS
functions in 1.0.0, and I had a couple of questions. Given the attached C
program:
1: Why is not the SID value filled in - it looks like it SHOULD be with a SKID
value.
2: How would I go about signing this structure - I already have the data I
need in eContent, so I don't think that it would be THAT interesting to dump
it out into a BIO just to use a higher level function? I understand the
utility of using a BIO, in the S/MIME context, but when you are dealing with
relatively small structures (such as those outlined in RFC5272) I think it
would be good to have a CMS_sign_signedData(CMS_ContentInfo *cms), or some
such, that would simply take the values already present in the CMS_signerInfos
structure and sign the signedData structure, without wanting to read back in
the content for eContent from a BIO.
Is there any easy way to do this? Have I missed some function that would allow
this?
Thanks in advance,
PS: The output of the example program, in Base64, is:
MIIDjAYJKoZIhvcNAQcCoIIDfTCCA3kCAQMxCTAHBgUrDgMCGjAaBgQqAwQFoBIEEBYOVGhpcyBpcyBhIHRlc3SgggMSMIIDDjCCAfagAwIBAgIJAIpS1zbJtrL4MA0GCSqGSIb3DQEBBQUAMA4xDDAKBgNVBAMTA2ZvbzAeFw0xMDExMTIxOTI1MjVaFw0xMDEyMTIxOTI1MjVaMA4xDDAKBgNVBAMTA2ZvbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMT5ugRqUQt1A2xeqAVOUWFUM3XMwaUIbMf9kcAlkR/jOIRa1eBKNmJed9or3STIwJ99c3FvAESNBUfqPBkTovQGfBT6PnsoWx4Yac6/345L3H2mWMgqA9FcGr9sooNyg+0yKsxwpYUilHg32i1KuOGvvEDL+0iMBcW9vir9sSAmhVO1fB18DFZJBoIj6hZwd5ZSPMF60CZJT9SIfi1OOmWK3X3TDb4zg3z7UX5X3qoEzLR4FTS2HctYHc8TJh3+BFZPLCvWvuA0AMEPvO8ob8eUZ4MHaWyPxktJqkXowW97T9ZYn8P0uOX4rBazWZ7113Pu36kBpmJ8SlTdalm6MNkCAwEAAaNvMG0wHQYDVR0OBBYEFIQ6kXG5Yu1TJjWNfC4rpw6zWcu0MD4GA1UdIwQ3MDWAFIQ6kXG5Yu1TJjWNfC4rpw6zWcu0oRKkEDAOMQwwCgYDVQQDEwNmb2+CCQCKUtc2ybay+DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBp2dOdpMf99piG5AuzCWucnmmvHO6texpvYdbboHeyUYxVKIWTY2mzK8kSC6CKS5s9nmy0BMwuKNM8la4jcoPENrwD9pHrHA+EWHy64waygxmK5WQiugM+HQb92aqZBGZF3MbjUCQT+1aJNnPaMNo5Yg+vziI4y6KGVPF5bLOaxx1kXPcUxUcUQ/SoQLUJ5xDXpMCSq106ykY9LDl0CuJN5tJIzAgTTSbT1l4sR2fA50XNSIvrkFjC4BvEmphGov+DFMhj7Bc8simNt9MhHfFNGwgkIyn9CimzNnFw/qvGusS+ZhuGPU2pry/Ni/QyOUlQDmcE3BvLNDqzaKqv5scQMTcwNQIBA4AUhDqRcbli7VMmNY18LiunDrNZy7QwBwYFKw4DAhqgADANBgkqhkiG9w0BAQEFAAQA
--
Patrick Patterson
Chief PKI Architect,
Carillon Information Security Inc.
http://www.carillon.ca
#include <wvstreams/wvstrutils.h>
#include <wvstreams/wvlog.h>
#include <wvstreams/wvbuf.h>
#include <unistd.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include "sd_helper.h"
char rsa[] = "-----BEGIN RSA PRIVATE KEY-----\n"
"MIIEpAIBAAKCAQEAxPm6BGpRC3UDbF6oBU5RYVQzdczBpQhsx/2RwCWRH+M4hFrV\n"
"4Eo2Yl532ivdJMjAn31zcW8ARI0FR+o8GROi9AZ8FPo+eyhbHhhpzr/fjkvcfaZY\n"
"yCoD0Vwav2yig3KD7TIqzHClhSKUeDfaLUq44a+8QMv7SIwFxb2+Kv2xICaFU7V8\n"
"HXwMVkkGgiPqFnB3llI8wXrQJklP1Ih+LU46ZYrdfdMNvjODfPtRflfeqgTMtHgV\n"
"NLYdy1gdzxMmHf4EVk8sK9a+4DQAwQ+87yhvx5RngwdpbI/GS0mqRejBb3tP1lif\n"
"w/S45fisFrNZnvXXc+7fqQGmYnxKVN1qWbow2QIDAQABAoIBABi5R7H6LkYD3/Qg\n"
"RXK1C93tla/5jWzLi+vmVf8KOBcKjDOAu0u1xPG/7cdCrjVJxXO/aVgZmK0CDmGi\n"
"cvyqzE9Y6QYxCtqmjBlQ8ybySnsv5nMXCBnHvEbxCqJwXk2leA2zuE+E7CGz33Lf\n"
"f9EjieU6C6UOdXH7sVXKpS38PdlNBAcCrFVOcPPcmGxOQoRkpbpwXwiLdnyyHREC\n"
"19p4KHXG/PViYJCbYqpgAqM/47Xz1fhE/9esEaa+A8f5Qp7hqV9OrCPnyz31Uitq\n"
"OjqYp//HnIlZPY4KNTAx2c1Bfi/Rq5EMxZQb8Gw4cJF9LkCy8CZ7XgPWAGMB9vr3\n"
"w9OdEQECgYEA7PYeNJIGMCswOxwQheGzHRKJKweevFc7j7uAY4/PJHlAun5HemC+\n"
"CdYUybHCaIKg8BMcyi4KGj/lXIhKgNeB9zfwLW8dDUrNS4OZupxSF8qs2NC+T04r\n"
"Ve3na4ePylWNJIJWE1z5eESdCkpttzOwvF4x9PoB0YRPUk7zM/qn3JECgYEA1M0r\n"
"H7XyhaSbTnOfiLi3z27efy48dSZcLqqONTa8LZOstGIYLmDiO+ppZKfYR3o/c+/A\n"
"Pt43tIjoIGHTlOa/g2jvabZw5b/0/QtIJeZybWKuiMDrVoP6ZzPmAsU3T1G0Df1r\n"
"14AkYK4HRR9PahgT+H8gzJVa8kba70e+Tqo7U8kCgYEA5MALFLDKrIFkxAspoDTr\n"
"leso45Mtl5+WbgCRxoszaoBrDh2NnwP5MMGru7GQfRdtiZTJvBuJwSFhp1wioBJq\n"
"8l7byuBy6TwGxxk5tD3nufP7vCp3LVPG3eMV/mYVVzwTTuVLdtHQOlvyRdbn521M\n"
"9erwyw715m6VrF1uxgT5OyECgYEAhUI1zxXRWX9LAkXFkYibEnsLOflqQrJS56ZG\n"
"h2xPSvs/G3aSTfi9s2eHuFCjT59uPNvWN4hQue1B74VTSdt18oSz6C8nY7hhYlS+\n"
"SX2WConRYjHtLbBYDmihkPqPOEyhxGD+N2U3YpOYWeDRik6psuNpVrPwz+cvEsiK\n"
"lBhmLoECgYAW8YAQR0PV+CBR7QJoc2LHyjVm7akc1XNXVfAi3dGsLW33Ph6aBysZ\n"
"LES6Nb30gR5tiwtExXyPmHz4Zs6HgNtosjZdoBD6TtSDJYtjl7x5Tlz5vxWasV25\n"
"jthCWaR4py+A4715UMybMwO4glM0UZ5+IxRhD5oSwOudCB2fBgOaEQ==\n"
"-----END RSA PRIVATE KEY-----\0";
char cert[] = "-----BEGIN CERTIFICATE-----\n"
"MIIDDjCCAfagAwIBAgIJAIpS1zbJtrL4MA0GCSqGSIb3DQEBBQUAMA4xDDAKBgNV\n"
"BAMTA2ZvbzAeFw0xMDExMTIxOTI1MjVaFw0xMDEyMTIxOTI1MjVaMA4xDDAKBgNV\n"
"BAMTA2ZvbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMT5ugRqUQt1\n"
"A2xeqAVOUWFUM3XMwaUIbMf9kcAlkR/jOIRa1eBKNmJed9or3STIwJ99c3FvAESN\n"
"BUfqPBkTovQGfBT6PnsoWx4Yac6/345L3H2mWMgqA9FcGr9sooNyg+0yKsxwpYUi\n"
"lHg32i1KuOGvvEDL+0iMBcW9vir9sSAmhVO1fB18DFZJBoIj6hZwd5ZSPMF60CZJ\n"
"T9SIfi1OOmWK3X3TDb4zg3z7UX5X3qoEzLR4FTS2HctYHc8TJh3+BFZPLCvWvuA0\n"
"AMEPvO8ob8eUZ4MHaWyPxktJqkXowW97T9ZYn8P0uOX4rBazWZ7113Pu36kBpmJ8\n"
"SlTdalm6MNkCAwEAAaNvMG0wHQYDVR0OBBYEFIQ6kXG5Yu1TJjWNfC4rpw6zWcu0\n"
"MD4GA1UdIwQ3MDWAFIQ6kXG5Yu1TJjWNfC4rpw6zWcu0oRKkEDAOMQwwCgYDVQQD\n"
"EwNmb2+CCQCKUtc2ybay+DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\n"
"AQBp2dOdpMf99piG5AuzCWucnmmvHO6texpvYdbboHeyUYxVKIWTY2mzK8kSC6CK\n"
"S5s9nmy0BMwuKNM8la4jcoPENrwD9pHrHA+EWHy64waygxmK5WQiugM+HQb92aqZ\n"
"BGZF3MbjUCQT+1aJNnPaMNo5Yg+vziI4y6KGVPF5bLOaxx1kXPcUxUcUQ/SoQLUJ\n"
"5xDXpMCSq106ykY9LDl0CuJN5tJIzAgTTSbT1l4sR2fA50XNSIvrkFjC4BvEmphG\n"
"ov+DFMhj7Bc8simNt9MhHfFNGwgkIyn9CimzNnFw/qvGusS+ZhuGPU2pry/Ni/Qy\n"
"OUlQDmcE3BvLNDqzaKqv5scQ\n"
"-----END CERTIFICATE-----\0";
int main(int argv, char **argc)
{
ERR_load_CMS_strings();
ERR_load_ERR_strings();
printf("Starting...\n");
BIO *membuf = BIO_new(BIO_s_mem());
BIO_write(membuf, rsa, strlen(rsa));
RSA *rsakey = PEM_read_bio_RSAPrivateKey(membuf, NULL, NULL, NULL);
EVP_PKEY *mykey = EVP_PKEY_new();
EVP_PKEY_set1_RSA(mykey, rsakey);
BIO_free(membuf);
printf("Got the RSA Key\n");
membuf = BIO_new(BIO_s_mem());
BIO_write(membuf, cert, strlen(cert));
X509 *x509 = PEM_read_bio_X509(membuf, NULL, NULL, NULL);
BIO_free(membuf);
printf("Got the Certificate\n");
WvDynBuf content_buf;
CMS_ContentInfo *cms = CMS_ContentInfo_new();
CMS_SignerInfo *si = CMS_add1_signer(cms, x509, mykey, EVP_sha1(),
CMS_USE_KEYID | CMS_NOSMIMECAP);
unsigned long err = ERR_get_error();
if (!si || err != 0)
printf("ERROR: %s\n", ERR_error_string(err, NULL));
/* Set type of the content appropriately */
CMS_set1_eContentType(cms, OBJ_txt2obj("1.2.3.4.5", 1));
ASN1_IA5STRING *ia5 = ASN1_IA5STRING_new();
ASN1_STRING_set(ia5, "This is a test", 14);
// Now fill the eContent appropriately.
size_t i = i2d_ASN1_IA5STRING(ia5, NULL);
unsigned char *p = content_buf.alloc(i);
i2d_ASN1_IA5STRING(ia5, &p);
size_t final = content_buf.used();
ASN1_OCTET_STRING **eContent = CMS_get0_content(cms);
*eContent = ASN1_OCTET_STRING_new();
ASN1_OCTET_STRING_set(*eContent, content_buf.get(final), final);
// We don't need to add the certificate as
// add1_signer already did that for us.
printf("%s\n", signedData2base64(cms).edit());
printf("Done!\n");
}