Improvements based on peer review. Added section in README.md.
parent
042956c74b
commit
45a13e1491
|
@ -252,3 +252,84 @@ bmQHbpv7R5cK0GP2bFkqggIgN1wA6w19lVFdjukGx6VvfYsdaY2O+Fu6Ew4qX7SG
|
||||||
GxI=
|
GxI=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Certificate Signing Request (CSR) Example with Crypto Callbacks
|
||||||
|
|
||||||
|
Example of generating a PEM-encoded certificate signing request (CSR) using the
|
||||||
|
Crypto Callbacks to show signing against HSM/TPM
|
||||||
|
|
||||||
|
Tested with these wolfSSL build options:
|
||||||
|
|
||||||
|
```
|
||||||
|
./configure --enable-certreq --enable-certgen --enable-certext --enable-cryptocb
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
### `csr_cryptocb` Example output
|
||||||
|
|
||||||
|
```
|
||||||
|
% ./csr_cryptocb
|
||||||
|
Invalid input supplied try one of the below examples
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
./csr_cryptocb rsa
|
||||||
|
./csr_cryptocb ecc
|
||||||
|
./csr_cryptocb ed25519
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
% ./csr_cryptocb ecc
|
||||||
|
CryptoCb: PK ECDSA-Sign (4)
|
||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIBTDCB8wIBAjCBkDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
|
||||||
|
DAhQb3J0bGFuZDEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRGV2ZWxvcG1l
|
||||||
|
bnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5m
|
||||||
|
b0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLszrEwnUErG
|
||||||
|
SqUEwzzenzbbci3OlOor+ssgCTksFuhhAumvTdMCk5oxW5eSIX/wzxjakRECNIbo
|
||||||
|
IFgzC4A0idigADAKBggqhkjOPQQDAgNIADBFAiEAmJK6ZapcFw4NTjImNoBrpudZ
|
||||||
|
6sFvRccABG35QyASvIsCIFXcN4Wo5qiH37OjT7dehbdZvQbJFw4hKOtim1gw5Z4p
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
|
(525)
|
||||||
|
Saved CSR PEM to "ecc-csr.pem"
|
||||||
|
|
||||||
|
```
|
||||||
|
% ./csr_cryptocb rsa
|
||||||
|
CryptoCb: PK RSA (1)
|
||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIC1jCCAb4CAQIwgZAxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJPUjERMA8GA1UE
|
||||||
|
BwwIUG9ydGxhbmQxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0RldmVsb3Bt
|
||||||
|
ZW50MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGlu
|
||||||
|
Zm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD
|
||||||
|
A9Er/jmkMkU7U8iEKyp8dJq9qipSB0fWpjayBzKO0Lppe8bDRJ7UgUj9LWiii2e7
|
||||||
|
oXXINixK0hv3i7rPDfnv7PGBHnubA0eav2XMf2UkaaboFIlb5DT3xbAUk/Vnezp6
|
||||||
|
eOEBVlaRphNCjdI8QJxM79GG3zdRGwyhO/Xxo0o15OHOlt8bfr9Ol9AQ6KgIMIGv
|
||||||
|
IAtDFMV0Z7Qygm+NhsKIQJk2g7oeQHIiF9dSZSRzsM7vGc2u/3hse8ASA9ROcg1Q
|
||||||
|
bTujO6OZXp3I2QyFs9mK2VQm2236rLv/JUzE0Xn0cdOGQBgTsGO1ck4wxJeEhi1W
|
||||||
|
L9cV93/ArvX8W+X7obrTAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAK+RxSIQ4
|
||||||
|
CqxYbicHcbFZgHrTy7MOoA8uM5XWIP/AKZ4u64zbF2K6XIMItrfIGEouc6MDfKVh
|
||||||
|
W8ml6O75SR/7h/8S/9GClqcuzFqtNflzmb20Oadkl09sRIXPhFXMpt4V+Zc4cOka
|
||||||
|
kcqL0q+oEU+8naRJJ6pa6LL1NWRq79es4DykvtHcGkx0J1VPlu3ux7iYlQ0fVfRs
|
||||||
|
QUI1z3K52qfuchKW5zwkDjkVDbiWPd0/pbtUW2f8TAC21h0NabwMGISrrxmu6SX2
|
||||||
|
wI8YHCyLX5sMUosQ78vuGBD0bD5rxil0lzO9pjvWiSLZe0ubJ2Qq+FiuqIqITRiy
|
||||||
|
5AMQEs5siVCCEA==
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
|
(1062)
|
||||||
|
Saved CSR PEM to "rsa-csr.pem"
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
% ./csr_cryptocb ed25519
|
||||||
|
CryptoCb: PK ED25519-Sign (6)
|
||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIBETCBxAIBAjCBkDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
|
||||||
|
DAhQb3J0bGFuZDEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRGV2ZWxvcG1l
|
||||||
|
bnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5m
|
||||||
|
b0B3b2xmc3NsLmNvbTAqMAUGAytlcAMhAOZXWxMbx1EUa+079dH6q55stusCCaOZ
|
||||||
|
9W6/nTz+VDnmoAAwBQYDK2VwA0EAZX+pExcyCYxJHJmmISW8AxfhgJ/PmTPK4+uH
|
||||||
|
7iTt+VTNvi/Z6IPjlg+UWIbyyCno0RoNnB7GiqnvPn8fVAcsAw==
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
|
(448)
|
||||||
|
Saved CSR PEM to "ed25519-csr.pem"
|
||||||
|
```
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Example of generating a PEM-encoded certificate signing request (CSR). */
|
/* Example of generating a PEM-encoded certificate signing request (CSR) using
|
||||||
|
* the Crypto Callbacks to show signing against HSM/TPM */
|
||||||
|
|
||||||
#ifndef WOLFSSL_USER_SETTINGS
|
#ifndef WOLFSSL_USER_SETTINGS
|
||||||
#include <wolfssl/options.h>
|
#include <wolfssl/options.h>
|
||||||
|
@ -37,8 +38,13 @@
|
||||||
#define DEBUG_CRYPTOCB
|
#define DEBUG_CRYPTOCB
|
||||||
|
|
||||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_CERT_REQ) && \
|
#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_CERT_REQ) && \
|
||||||
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
|
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && \
|
||||||
|
(!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519))
|
||||||
|
|
||||||
|
#define ENABLE_CSR_EXAMPLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_CSR_EXAMPLE
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
printf("Invalid input supplied try one of the below examples\n");
|
printf("Invalid input supplied try one of the below examples\n");
|
||||||
|
@ -54,6 +60,122 @@ typedef struct {
|
||||||
const char* keyFilePriv;
|
const char* keyFilePriv;
|
||||||
} myCryptoCbCtx;
|
} myCryptoCbCtx;
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
static int load_key_file(const char* fname, byte* derBuf, word32* derLen,
|
||||||
|
int isPubKey);
|
||||||
|
#ifdef DEBUG_CRYPTOCB
|
||||||
|
static const char* GetAlgoTypeStr(int algo);
|
||||||
|
static const char* GetPkTypeStr(int pk);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Example crypto dev callback function that calls software version */
|
||||||
|
/* This is where you would plug-in calls to your own hardware crypto */
|
||||||
|
static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||||
|
{
|
||||||
|
int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */
|
||||||
|
myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx;
|
||||||
|
byte der[LARGE_TEMP_SZ];
|
||||||
|
word32 derSz;
|
||||||
|
word32 idx = 0;
|
||||||
|
|
||||||
|
if (info == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
ret = load_key_file(myCtx->keyFilePriv, der, &derSz, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("Error %d loading %s\n", ret, myCtx->keyFilePriv);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->algo_type == WC_ALGO_TYPE_PK) {
|
||||||
|
#ifdef DEBUG_CRYPTOCB
|
||||||
|
printf("CryptoCb: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type),
|
||||||
|
GetPkTypeStr(info->pk.type), info->pk.type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_RSA
|
||||||
|
if (info->pk.type == WC_PK_TYPE_RSA) {
|
||||||
|
RsaKey rsaPriv;
|
||||||
|
ret = wc_InitRsaKey_ex(&rsaPriv, NULL, INVALID_DEVID);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = wc_RsaPrivateKeyDecode(der, &idx, &rsaPriv, derSz);
|
||||||
|
if (ret != 0) {
|
||||||
|
wc_FreeRsaKey(&rsaPriv);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (info->pk.rsa.type) {
|
||||||
|
case RSA_PUBLIC_ENCRYPT:
|
||||||
|
case RSA_PUBLIC_DECRYPT:
|
||||||
|
/* perform software based RSA public op */
|
||||||
|
ret = wc_RsaFunction(
|
||||||
|
info->pk.rsa.in, info->pk.rsa.inLen,
|
||||||
|
info->pk.rsa.out, info->pk.rsa.outLen,
|
||||||
|
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
|
||||||
|
break;
|
||||||
|
case RSA_PRIVATE_ENCRYPT:
|
||||||
|
case RSA_PRIVATE_DECRYPT:
|
||||||
|
/* perform software based RSA private op */
|
||||||
|
ret = wc_RsaFunction(
|
||||||
|
info->pk.rsa.in, info->pk.rsa.inLen,
|
||||||
|
info->pk.rsa.out, info->pk.rsa.outLen,
|
||||||
|
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wc_FreeRsaKey(&rsaPriv);
|
||||||
|
}
|
||||||
|
#endif /* !NO_RSA */
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
|
||||||
|
ecc_key eccPriv;
|
||||||
|
ret = wc_ecc_init_ex(&eccPriv, NULL, INVALID_DEVID);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_EccPrivateKeyDecode(der, &idx, &eccPriv, derSz);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_ecc_sign_hash(
|
||||||
|
info->pk.eccsign.in, info->pk.eccsign.inlen,
|
||||||
|
info->pk.eccsign.out, info->pk.eccsign.outlen,
|
||||||
|
info->pk.eccsign.rng, &eccPriv);
|
||||||
|
}
|
||||||
|
wc_ecc_free(&eccPriv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#ifdef HAVE_ED25519
|
||||||
|
if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
|
||||||
|
ed25519_key edPriv;
|
||||||
|
ret = wc_ed25519_init_ex(&edPriv, NULL, INVALID_DEVID);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_Ed25519PrivateKeyDecode(der, &idx, &edPriv, derSz);
|
||||||
|
if (ret == 0) {
|
||||||
|
/* calculate public key */
|
||||||
|
ret = wc_ed25519_make_public(&edPriv, edPriv.p,
|
||||||
|
ED25519_PUB_KEY_SIZE);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
edPriv.pubKeySet = 1;
|
||||||
|
ret = wc_ed25519_sign_msg_ex(
|
||||||
|
info->pk.ed25519sign.in, info->pk.ed25519sign.inLen,
|
||||||
|
info->pk.ed25519sign.out, info->pk.ed25519sign.outLen,
|
||||||
|
&edPriv, info->pk.ed25519sign.type,
|
||||||
|
info->pk.ed25519sign.context,
|
||||||
|
info->pk.ed25519sign.contextLen);
|
||||||
|
}
|
||||||
|
wc_ed25519_free(&edPriv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ED25519 */
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)devIdArg;
|
||||||
|
(void)myCtx;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_CRYPTOCB
|
#ifdef DEBUG_CRYPTOCB
|
||||||
static const char* GetAlgoTypeStr(int algo)
|
static const char* GetAlgoTypeStr(int algo)
|
||||||
{
|
{
|
||||||
|
@ -193,113 +315,6 @@ static int save_der_as_pem(const byte* der, word32 derSz, const char* arg1,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Example crypto dev callback function that calls software version */
|
|
||||||
/* This is where you would plug-in calls to your own hardware crypto */
|
|
||||||
static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
|
||||||
{
|
|
||||||
int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */
|
|
||||||
myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx;
|
|
||||||
byte der[LARGE_TEMP_SZ];
|
|
||||||
word32 derSz;
|
|
||||||
word32 idx = 0;
|
|
||||||
|
|
||||||
if (info == NULL)
|
|
||||||
return BAD_FUNC_ARG;
|
|
||||||
|
|
||||||
ret = load_key_file(myCtx->keyFilePriv, der, &derSz, 0);
|
|
||||||
if (ret != 0) {
|
|
||||||
printf("Error %d loading %s\n", ret, myCtx->keyFilePriv);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->algo_type == WC_ALGO_TYPE_PK) {
|
|
||||||
#ifdef DEBUG_CRYPTOCB
|
|
||||||
printf("CryptoCb: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type),
|
|
||||||
GetPkTypeStr(info->pk.type), info->pk.type);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_RSA
|
|
||||||
if (info->pk.type == WC_PK_TYPE_RSA) {
|
|
||||||
RsaKey rsaPriv;
|
|
||||||
ret = wc_InitRsaKey_ex(&rsaPriv, NULL, INVALID_DEVID);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ret = wc_RsaPrivateKeyDecode(der, &idx, &rsaPriv, derSz);
|
|
||||||
if (ret != 0) {
|
|
||||||
wc_FreeRsaKey(&rsaPriv);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (info->pk.rsa.type) {
|
|
||||||
case RSA_PUBLIC_ENCRYPT:
|
|
||||||
case RSA_PUBLIC_DECRYPT:
|
|
||||||
/* perform software based RSA public op */
|
|
||||||
ret = wc_RsaFunction(
|
|
||||||
info->pk.rsa.in, info->pk.rsa.inLen,
|
|
||||||
info->pk.rsa.out, info->pk.rsa.outLen,
|
|
||||||
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
|
|
||||||
break;
|
|
||||||
case RSA_PRIVATE_ENCRYPT:
|
|
||||||
case RSA_PRIVATE_DECRYPT:
|
|
||||||
/* perform software based RSA private op */
|
|
||||||
ret = wc_RsaFunction(
|
|
||||||
info->pk.rsa.in, info->pk.rsa.inLen,
|
|
||||||
info->pk.rsa.out, info->pk.rsa.outLen,
|
|
||||||
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wc_FreeRsaKey(&rsaPriv);
|
|
||||||
}
|
|
||||||
#endif /* !NO_RSA */
|
|
||||||
#ifdef HAVE_ECC
|
|
||||||
if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
|
|
||||||
ecc_key eccPriv;
|
|
||||||
ret = wc_ecc_init_ex(&eccPriv, NULL, INVALID_DEVID);
|
|
||||||
if (ret == 0) {
|
|
||||||
ret = wc_EccPrivateKeyDecode(der, &idx, &eccPriv, derSz);
|
|
||||||
if (ret == 0) {
|
|
||||||
ret = wc_ecc_sign_hash(
|
|
||||||
info->pk.eccsign.in, info->pk.eccsign.inlen,
|
|
||||||
info->pk.eccsign.out, info->pk.eccsign.outlen,
|
|
||||||
info->pk.eccsign.rng, &eccPriv);
|
|
||||||
}
|
|
||||||
wc_ecc_free(&eccPriv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* HAVE_ECC */
|
|
||||||
#ifdef HAVE_ED25519
|
|
||||||
if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
|
|
||||||
ed25519_key edPriv;
|
|
||||||
ret = wc_ed25519_init_ex(&edPriv, NULL, INVALID_DEVID);
|
|
||||||
if (ret == 0) {
|
|
||||||
ret = wc_Ed25519PrivateKeyDecode(der, &idx, &edPriv, derSz);
|
|
||||||
if (ret == 0) {
|
|
||||||
/* calculate public key */
|
|
||||||
ret = wc_ed25519_make_public(&edPriv, edPriv.p,
|
|
||||||
ED25519_PUB_KEY_SIZE);
|
|
||||||
}
|
|
||||||
if (ret == 0) {
|
|
||||||
edPriv.pubKeySet = 1;
|
|
||||||
ret = wc_ed25519_sign_msg_ex(
|
|
||||||
info->pk.ed25519sign.in, info->pk.ed25519sign.inLen,
|
|
||||||
info->pk.ed25519sign.out, info->pk.ed25519sign.outLen,
|
|
||||||
&edPriv, info->pk.ed25519sign.type,
|
|
||||||
info->pk.ed25519sign.context,
|
|
||||||
info->pk.ed25519sign.contextLen);
|
|
||||||
}
|
|
||||||
wc_ed25519_free(&edPriv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* HAVE_ED25519 */
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)devIdArg;
|
|
||||||
(void)myCtx;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gen_csr(const char* arg1)
|
static int gen_csr(const char* arg1)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -328,8 +343,10 @@ static int gen_csr(const char* arg1)
|
||||||
type = ECC_TYPE;
|
type = ECC_TYPE;
|
||||||
else if (XSTRNCMP(arg1, "ed25519", 7) == 0)
|
else if (XSTRNCMP(arg1, "ed25519", 7) == 0)
|
||||||
type = ED25519_TYPE;
|
type = ED25519_TYPE;
|
||||||
else
|
else {
|
||||||
|
printf("Invalid argument or not compiled in (expect: rsa, ecc or ed25519)\n");
|
||||||
return NOT_COMPILED_IN;
|
return NOT_COMPILED_IN;
|
||||||
|
}
|
||||||
|
|
||||||
wolfCrypt_Init();
|
wolfCrypt_Init();
|
||||||
|
|
||||||
|
@ -490,16 +507,15 @@ exit:
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
#if !defined(WOLF_CRYPTO_CB) || !defined(WOLFSSL_CERT_REQ) || \
|
#ifdef ENABLE_CSR_EXAMPLE
|
||||||
!defined(WOLFSSL_CERT_EXT) || !defined(WOLFSSL_CERT_GEN)
|
|
||||||
printf("Please compile wolfSSL with --enable-certreq --enable-certgen --enable-certext --enable-cryptocb\n");
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
usage();
|
usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gen_csr(argv[1]);
|
return gen_csr(argv[1]);
|
||||||
|
#else
|
||||||
|
printf("Please compile wolfSSL with --enable-certreq --enable-certgen --enable-certext --enable-cryptocb\n");
|
||||||
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue