Skip to content

Commit

Permalink
Supporting PKCS7 command for parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
lealem47 committed Oct 22, 2024
1 parent 3bf602f commit 07892ff
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/clu_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ static const struct option mode_options[] = {
{"ed25519", no_argument, 0, WOLFCLU_ED25519 },
{"dgst", no_argument, 0, WOLFCLU_DGST },
{"verify", no_argument, 0, WOLFCLU_VERIFY },
{"pkcs7", no_argument, 0, WOLFCLU_PKCS7 },
{"pkcs12", no_argument, 0, WOLFCLU_PKCS12 },
{"crl", no_argument, 0, WOLFCLU_CRL },
{"s_client", no_argument, 0, WOLFCLU_CLIENT },
Expand Down Expand Up @@ -278,6 +279,10 @@ int main(int argc, char** argv)
ret = wolfCLU_sign_verify_setup(argc, argv);
break;

case WOLFCLU_PKCS7:
ret = wolfCLU_PKCS7(argc, argv);
break;

case WOLFCLU_PKCS12:
ret = wolfCLU_PKCS12(argc, argv);
break;
Expand Down
3 changes: 2 additions & 1 deletion src/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ wolfssl_SOURCES = src/clu_main.c \
src/dsa/clu_dsa.c \
src/dh/clu_dh.c \
src/server/server.c \
src/server/clu_server_setup.c
src/server/clu_server_setup.c \
src/pkcs/clu_pkcs7.c


245 changes: 245 additions & 0 deletions src/pkcs/clu_pkcs7.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
/* clu_pkcs7.c
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

#include <wolfclu/clu_header_main.h>
#include <wolfclu/clu_log.h>
#include <wolfclu/clu_optargs.h>
#include <wolfclu/pkey/clu_pkey.h>
#include <wolfclu/x509/clu_cert.h>
#include <wolfclu/x509/clu_parse.h>

#ifndef WOLFCLU_NO_FILESYSTEM

static const struct option pkcs7_options[] = {
{"-print_certs", no_argument, 0, WOLFCLU_CERTFILE },
{"-in", required_argument, 0, WOLFCLU_INFILE },
{"-out", required_argument, 0, WOLFCLU_OUTFILE },
{"-inform", required_argument, 0, WOLFCLU_INFORM },
{"-outform", required_argument, 0, WOLFCLU_OUTFORM },
{"-help", no_argument, 0, WOLFCLU_HELP },
{"-h", no_argument, 0, WOLFCLU_HELP },

{0, 0, 0, 0} /* terminal element */
};


static void wolfCLU_pKeyHelp(void)
{
WOLFCLU_LOG(WOLFCLU_L0, "./wolfssl pkcs7");
WOLFCLU_LOG(WOLFCLU_L0, "\t-in file input for pkcs7");
WOLFCLU_LOG(WOLFCLU_L0, "\t-out file to write results to (default stdout)");
WOLFCLU_LOG(WOLFCLU_L0, "\t-inform pem/der");
WOLFCLU_LOG(WOLFCLU_L0, "\t-outform pem/der");
WOLFCLU_LOG(WOLFCLU_L0, "\t-print_certs output certificates");
}
#endif

int wolfCLU_PKCS7(int argc, char** argv)
{
#if defined(HAVE_PKCS7) && !defined(WOLFCLU_NO_FILESYSTEM)
int ret = WOLFCLU_SUCCESS;
int printCerts = 0; /* default to no */
int option;
int longIndex = 1;
int inForm = PEM_FORM;
int outForm = PEM_FORM;
PKCS7 pkcs7;
WOLFSSL_BIO *bioIn = NULL;
WOLFSSL_BIO *bioOut = NULL;
DerBuffer* derObj = NULL;
byte* buf = NULL;
byte* derContent = NULL;
int bufSz;
int derContentSz;

opterr = 0; /* do not display unrecognized options */
optind = 0; /* start at indent 0 */
while ((option = wolfCLU_GetOpt(argc, argv, "",
pkcs7_options, &longIndex )) != -1) {
switch (option) {
case WOLFCLU_CERTFILE:
printCerts = 1;
break;

case WOLFCLU_INFILE:
bioIn = wolfSSL_BIO_new_file(optarg, "rb");
if (bioIn == NULL) {
wolfCLU_LogError("Unable to open pkcs7 file %s",
optarg);
ret = WOLFCLU_FATAL_ERROR;
}
break;

case WOLFCLU_OUTFILE:
bioOut = wolfSSL_BIO_new_file(optarg, "wb");
if (bioOut == NULL) {
wolfCLU_LogError("Unable to open output file %s",
optarg);
ret = WOLFCLU_FATAL_ERROR;
}
break;

case WOLFCLU_INFORM:
inForm = wolfCLU_checkInform(optarg);
break;

case WOLFCLU_OUTFORM:
outForm = wolfCLU_checkOutform(optarg);
break;

case WOLFCLU_HELP:
wolfCLU_pKeyHelp();
return WOLFCLU_SUCCESS;

case ':':
case '?':
wolfCLU_LogError("Bad argument found");
wolfCLU_pKeyHelp();
ret = WOLFCLU_FATAL_ERROR;
break;

default:
/* do nothing. */
(void)ret;
}
}

/* currently only supporting PKCS7 parsing, an input file is expected */
if (ret == WOLFCLU_SUCCESS && bioIn == NULL) {
wolfCLU_LogError("No input file set");
ret = WOLFCLU_FATAL_ERROR;
}

/* read the input bio to a temporary buffer and convert to PKCS7 */
if (ret == WOLFCLU_SUCCESS) {
bufSz = wolfSSL_BIO_get_len(bioIn);
if (bufSz > 0) {
buf = (byte*)XMALLOC(bufSz, HEAP_HINT, DYNAMIC_TYPE_PKCS);
if (buf == NULL) {
ret = WOLFCLU_FATAL_ERROR;
}
else {
/* reading the full file into a buffer */
if (wolfSSL_BIO_read(bioIn, buf, bufSz) != bufSz) {
ret = WOLFCLU_FATAL_ERROR;
}
else {
if (wc_PKCS7_Init(&pkcs7, HEAP_HINT, INVALID_DEVID)) {
wolfCLU_LogError("Error on pkcs init");
ret = WOLFCLU_FATAL_ERROR;
}
if (ret == WOLFCLU_SUCCESS &&
wc_PKCS7_InitWithCert(&pkcs7, HEAP_HINT, 0)) {
wolfCLU_LogError("Error on pkcs initWithCert");
ret = WOLFCLU_FATAL_ERROR;
}

if (ret == WOLFCLU_SUCCESS && inForm == PEM_FORM) {
if (wc_PemToDer(buf, bufSz, PKCS7_TYPE, &derObj,
HEAP_HINT, NULL, NULL) == 0) {
derContent = derObj->buffer;
derContentSz = derObj->length;

}
else {
ret = WOLFCLU_FATAL_ERROR;
}
}
else if (ret == WOLFCLU_SUCCESS) {
derContent = buf;
derContentSz = bufSz;
}

if (ret == WOLFCLU_SUCCESS && wc_PKCS7_VerifySignedData(
&pkcs7, derContent, derContentSz)) {
wolfCLU_LogError("Error reading pkcs7 file");
ret = WOLFCLU_FATAL_ERROR;
}
}
}
}
else {
wolfCLU_LogError("Error getting length of pkcs7 file");
ret = WOLFCLU_FATAL_ERROR;
}
}


/* setup output bio to stdout if not already set */
if (ret == WOLFCLU_SUCCESS && bioOut == NULL) {
bioOut = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
if (bioOut == NULL) {
ret = WOLFCLU_FATAL_ERROR;
}
else {
if (wolfSSL_BIO_set_fp(bioOut, stdout, BIO_NOCLOSE)
!= WOLFSSL_SUCCESS) {
ret = WOLFCLU_FATAL_ERROR;
}
}
}

/* print out the certificates */
if (ret == WOLFCLU_SUCCESS && printCerts) {
for (int i = 0; i < MAX_PKCS7_CERTS; i++) {
if (pkcs7.certSz[i] > 0) {
wolfCLU_printDer(bioOut, pkcs7.cert[i],pkcs7.certSz[i],
CERT_TYPE, DYNAMIC_TYPE_TMP_BUFFER);
}
else {
break;
}
}
}
else if (ret == WOLFCLU_SUCCESS && outForm == PEM_FORM) {
ret = wolfCLU_printDer(bioOut, derContent, derContentSz, PKCS7_TYPE,
DYNAMIC_TYPE_TMP_BUFFER);
}
else if (ret == WOLFCLU_SUCCESS && outForm == DER_FORM) {
if (wolfSSL_BIO_write(bioOut, derContent, derContentSz) <= 0) {
ret = WOLFCLU_FATAL_ERROR;
}
}

wolfSSL_BIO_free(bioIn);
wolfSSL_BIO_free(bioOut);
wc_PKCS7_Free(&pkcs7);

if (derObj != NULL)
wc_FreeDer(&derObj);

if (buf != NULL)
XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_PKCS);

return ret;
#else
(void)argc;
(void)argv;
#ifndef HAVE_PKCS7
wolfCLU_LogError("Recompile wolfSSL with PKCS7 support");
#endif
#ifdef WOLFCLU_NO_FILESYSTEM
wolfCLU_LogError("No filesystem support");
#endif
return WOLFCLU_FATAL_ERROR;
#endif
}

5 changes: 5 additions & 0 deletions wolfclu/clu_header_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,11 @@ int wolfCLU_GetTypeFromPKEY(WOLFSSL_EVP_PKEY* key);
*/
void wolfCLU_convertToLower(char* s, int sSz);

/**
* @brief handles PKCS7 command
*/
int wolfCLU_PKCS7(int argc, char** argv);


/**
* @brief handles PKCS12 command
Expand Down
1 change: 1 addition & 0 deletions wolfclu/clu_optargs.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ enum {
WOLFCLU_GEN_KEY,
WOLFCLU_ECPARAM,
WOLFCLU_PKEY,
WOLFCLU_PKCS7,
WOLFCLU_PKCS12,
WOLFCLU_CLIENT,
WOLFCLU_SERVER,
Expand Down

0 comments on commit 07892ff

Please sign in to comment.