Topic: Cannot sign a cert...
Hello,
See subject line.
I am trying to create and sign a certificate on the fly. I've gone through the examples (some with bugs), dug through API doc, debugged over and over... and managed to piece together this sequence.
The code, and a dummy CA cert/key are attached.
The code below simply does (or is supposed to)
[1]Create a 2048 key pair
[2]Convert it to DER
[3]Then convert it to PEM
[4]Save the private key.pem
[5]Create a Cert
[6]Load a CA
[7]Set the issuer
[8]Make the cert
[9]Load the CA Key
[10]Decode the CA key
[11]Sign the Cert
[12]Convert the Cert to PEM
[13]Save the Cert.pem
It gives a corrupted PEM file.
I've gone as far as creating a self signed and it works. Adding the steps to load the CA, set issuer, signed it are creating the bad PEM. I can't remove any of those individual steps to see what is breaking.
This is a Windows based build as a first development concept.
Since this will ultimately be embedded without a file system, the code loads the ca/key and runs from memory buffers.
The last half of the PEM is simply uninitialized memory.
-----BEGIN CERTIFICATE-----
MIICeKADAgECAhAIA+FO9NCldJWF6ua77BzkMA0GCSqGSIb3DQEBBQUAMHsxCzAJ
BgNVBAYTAlhYMQswCQYDVQQIDAJYWDEQMA4GA1UEBwwHQW55Q2l0eTENMAsGA1UE
CgwERGVtbzENMAsGA1UECwwERGVtbzERMA8GA1UEAwwIZGVtby5jb20xHDAaBgkq
hkiG9w0BCQEWDWluZm9ARGVtby5jb20wIhgPMjAyMTA2MDMxMzAxMzVaGA8yMDIy
MTAxNzEzMDEzNVowgYgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJaWjESMBAGA1UE
BwwJVGhpcyBDaXR5MQ0wCwYDVQQKDARZYWRhMQwwCgYDVQQLDANEZXYxGTAXBgNV
BAMMEHd3dy53aGF0ZXZlci5jb20xIDAeBgkqhkiG9w0BCQEWEUluZm9Ad2hhdGV2
ZXIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Ilzmeb9p6h0
fB5uNXkxNbuFvPP3lXVoOqM9wpz+yD/I/tL7EmWjgGkrjC0EBFPp6GwGbeWMR8Ui
4nQNTSYuCSJXUv/W/q4pvyEcx4CM+Of5GxUNRnDrQeVbHoiWfum2TGqPngzJVGiO
7ji6j3xlGUqQowS3CNQVAmKcXdVXaWJWyFfzbl5AjBlRjUgX08YsXc1bP7Wg291Z
88U7aY2skIgv1TJiftZrlxvPHa+uRMql5OS6cQkQ2psXRvEHurvwkij4MMUJaoCs
0uRmX8qDy1tXX/GwN6kGFcuoPJwNH7tP3adTFFrmWeevLL5n1xZmWovor15CxpXC
BsxPwKdclwIDAQABzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
zMzMzMzMzMzMzMzMzMzMzMzMzMw=
-----END CERTIFICATE-----
This is the code being used. ALL the return codes are good (even though they are not tested, they are good as I step through with the debugger)
#include <stdio.h>
#include "wolfssl\ssl.h"
#include "wolfssl/wolfcrypt\asn_public.h" /* Used for cert generation */
#include "wolfssl/wolfcrypt/rsa.h" /* Used for RNG and RSA Key */
int main() {
RsaKey genKey;
int result;
RNG rng;
FILE *fp;
wc_InitRng(&rng);
wc_InitRsaKey(&genKey,0);
wc_MakeRsaKey(&genKey, 2048, 65537, &rng);
/* Save off the private key we are going to use */
byte keyDer[4096];
int keysize, keypemsize;
keysize = wc_RsaKeyToDer(&genKey, keyDer, 4096);
byte keypem[4096];
keypemsize = wc_DerToPem(keyDer, keysize, keypem, 4096, PRIVATEKEY_TYPE);
/* Save the new private key */
fp = fopen("TestprivateKey.pem", "w+");
fwrite(keypem, 1, keypemsize, fp);
fclose(fp);
/* Create a CERT */
Cert testcert;
wc_InitCert(&testcert);
strcpy(testcert.subject.country, "US");
strcpy(testcert.subject.state, "ZZ");
strcpy(testcert.subject.locality, "This City");
strcpy(testcert.subject.org, "Yada");
strcpy(testcert.subject.unit, "Dev");
strcpy(testcert.subject.commonName, "www.whatever.com");
strcpy(testcert.subject.email, "Info@whatever.com");
byte dercert[4096];
int certsize, certpemsize;
/* Use for SELF SIGNED */
//certsize = wc_MakeSelfCert(&testcert, dercert, 4096, &genKey, &rng);
/* Use to sign it */
/* Load the CA cert to use */
int cacertbufsize;
unsigned char cacertbuf[4096];
byte cacertder[4096];
fp = fopen("sampleCA.pem", "r");
cacertbufsize = fread(cacertbuf, 1, 4096, fp);
fclose(fp);
/* Need to convert it to DER */
cacertbufsize = wc_CertPemToDer(cacertbuf, cacertbufsize, cacertder, 4096, CERT_TYPE);
result = wc_SetIssuerBuffer(&testcert, cacertder, cacertbufsize);
/* Now we can make the certificate */
certsize = wc_MakeCert(&testcert, dercert, 4096, &genKey, NULL, &rng);
/* Now load the CA key */
RsaKey cakey;
int cakeybufsize;
unsigned char cakeybuf[4096];
word32 idx = 0;
fp = fopen("sampleCAkey.pem", "r");
cakeybufsize = fread(cakeybuf, 1, 4096, fp);
fclose(fp);
unsigned char caderkey[4096];
/* Need to conver it to DER */
wc_InitRsaKey(&cakey, 0);
cakeybufsize = wc_KeyPemToDer(cakeybuf, cakeybufsize, caderkey, 4096, "ByteMe");
result = wc_RsaPrivateKeyDecode((const byte *)caderkey, &idx,&cakey, cakeybufsize);
/* Now we sign the certificate */
byte signedcert[4096];
certsize = wc_SignCert(testcert.bodySz, testcert.sigType, signedcert, 4096, &cakey, NULL, &rng);
/* Convert the DER to PEM */
byte pemcert[4096];
certpemsize = wc_DerToPem(dercert, certsize, pemcert, 4096, CERT_TYPE);
/* Save the signed signed cert */
fp = fopen("TestprivateCert.pem", "w+");
fwrite(pemcert, 1, certpemsize, fp);
fclose(fp);
return 0;
}
<Code shown is not to scale>