From 891cb7498a116235b9d0dcf5e06a44315a184a56 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 25 Aug 2016 11:50:26 -0600 Subject: [PATCH] add cert field extraction example --- README.md | 8 +++ certfields/Makefile | 11 ++++ certfields/README.md | 25 ++++++++ certfields/main.c | 140 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 certfields/Makefile create mode 100644 certfields/README.md create mode 100644 certfields/main.c diff --git a/README.md b/README.md index a087a2cc..befd7f4b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,14 @@ on the Android platform, using the Android NDK toolchain. Please see the README.md in android/ for further usage and details. +#### certfields (X509 field extraction) + +This directory contains an example that demonstrate using the wolfSSL +to read a DER encoded certificate and extract the public key and +subject name information. + +Please see the README.md in certfields/ for further usage and details. + #### certmanager (wolfSSL CertManager) This directory contains examples that demonstrate using the wolfSSL diff --git a/certfields/Makefile b/certfields/Makefile new file mode 100644 index 00000000..602d6586 --- /dev/null +++ b/certfields/Makefile @@ -0,0 +1,11 @@ +CC=gcc +CFLAGS=-Wall +LIBS= -lwolfssl + +app: main.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +.PHONY: clean + +clean: + rm -f *.o app diff --git a/certfields/README.md b/certfields/README.md new file mode 100644 index 00000000..e335baab --- /dev/null +++ b/certfields/README.md @@ -0,0 +1,25 @@ +# wolfSSL X509 Field Extraction Example + +Example of parsing a DER encoded self-signed certificate and extracting +public key and subject name information. + +## Compiling and Running the Example + +To compile, first build wolfSSL with the OpenSSL compatibilty layer enabled: + +``` +$ cd wolfssl-X.X.X +$ ./configure --enable-opensslextra +$ make +$ sudo make install +``` + +Then, compile the example app: + +``` +$ make +$ ./app +``` + +For support, please contact support@wolfssl.com + diff --git a/certfields/main.c b/certfields/main.c new file mode 100644 index 00000000..33861288 --- /dev/null +++ b/certfields/main.c @@ -0,0 +1,140 @@ +/* main.c + * + * Copyright (C) 2006-2016 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 + */ + +/* + * Example of parsing a DER-encoded certificate and extracting + * public key and subject name information. + * + */ + +#include +#include +#include +#include +#include + +static void err_sys(const char* msg, int ret) +{ + if (ret) { + printf("ERROR: %s, ret = %d\n", msg, ret); + } else { + printf("ERROR: %s\n", msg); + } + exit(EXIT_FAILURE); +} + +int main(void) +{ + int ret, i; + int sigType; + int nameSz; + int derCertSz; + byte derCert[4096]; + word32 idx; + FILE* file; + + RsaKey pubKey; + WOLFSSL_X509* cert; + WOLFSSL_EVP_PKEY* pubKeyTmp; + WOLFSSL_X509_NAME* name; + + char commonName[80]; + char countryName[80]; + char localityName[80]; + char stateName[80]; + char orgName[80]; + char orgUnit[80]; + + /* ------ PARSE ORIGINAL SELF-SIGNED CERTIFICATE ------ */ + + /* open and read DER-formatted cert into buffer */ + file = fopen("../certs/client-cert.der", "rb"); + if (!file) + err_sys("can't open client certificate", 0); + + derCertSz = fread(derCert, 1, sizeof(derCert), file); + fclose(file); + + /* convert cert from DER to internal WOLFSSL_X509 struct */ + cert = wolfSSL_X509_d2i(&cert, derCert, derCertSz); + if (cert == NULL) + err_sys("Failed to convert DER to WOLFSSL_X509", 0); + + /* ------ EXTRACT CERTIFICATE ELEMENTS ------ */ + + /* extract PUBLIC KEY from cert */ + pubKeyTmp = wolfSSL_X509_get_pubkey(cert); + if (pubKeyTmp == NULL) + err_sys("wolfSSL_X509_get_pubkey failed", 0); + + wc_InitRsaKey(&pubKey, 0); + idx = 0; + ret = wc_RsaPublicKeyDecode((byte*)pubKeyTmp->pkey.ptr, &idx, &pubKey, + pubKeyTmp->pkey_sz); + if (ret != 0) + err_sys("wc_RsaPublicKeyDecode failed", ret); + + printf("PUBLIC KEY:\n"); + for (i = 0; i < pubKeyTmp->pkey_sz; i++) { + printf("%02X", pubKeyTmp->pkey.ptr[i] & 0xFF); + } printf("\n"); + + /* extract signatureType */ + sigType = wolfSSL_X509_get_signature_type(cert); + if (sigType == 0) + err_sys("wolfSSL_X509_get_signature_type failed", 0); + printf("SIG TYPE = %d\n", sigType); + + /* extract subjectName info */ + name = wolfSSL_X509_get_subject_name(cert); + if (name == NULL) + err_sys("wolfSSL_X509_get_subject_name failed", 0); + + nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, ASN_COMMON_NAME, + commonName, sizeof(commonName)); + printf("CN = %s\n", commonName); + + nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, ASN_COUNTRY_NAME, + countryName, sizeof(countryName)); + printf("COUNTRY = %s\n", countryName); + + nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, ASN_LOCALITY_NAME, + localityName, sizeof(localityName)); + printf("LOCALITY = %s\n", localityName); + + nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, ASN_STATE_NAME, + stateName, sizeof(stateName)); + printf("STATE = %s\n", stateName); + + nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, ASN_ORG_NAME, + orgName, sizeof(orgName)); + printf("ORG = %s\n", orgName); + + nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, ASN_ORGUNIT_NAME, + orgUnit, sizeof(orgUnit)); + printf("ORG UNIT = %s\n", orgUnit); + + wolfSSL_EVP_PKEY_free(pubKeyTmp); + wolfSSL_X509_free(cert); + + return 0; +} +