extractCertFields.cpp [plain text]
#include <utilLib/common.h>
#include <utilLib/cspwrap.h>
#include <security_cdsa_utils/cuFileIo.h>
#include <security_cdsa_utils/cuPrintCert.h>
#include <clAppUtils/clutils.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <Security/cssm.h>
#include <Security/oidscert.h>
#include <Security/SecAsn1Coder.h>
#include <Security/X509Templates.h>
#define WRITE_NAME_FILE 1
#define SUBJECT_NAME_OID CSSMOID_X509V1SubjectName
static void dumpDataBlob(
const char *label,
const CSSM_DATA_PTR data)
{
unsigned i;
printf("static const uint8 %s_bytes[] = {\n ", label);
for(i=0; i<data->Length; i++) {
printf("0x%02x", data->Data[i]);
if(i != (data->Length - 1)) {
printf(", ");
}
if((i % 8) == 7) {
printf("\n ");
}
}
printf("\n};\n");
printf("static const CSSM_DATA %s = { %lu, (uint8 *)%s_bytes };\n",
label, data->Length, label);
}
static void printHeader(
const char *fileName,
CSSM_DATA_PTR subject)
{
CSSM_FIELD field;
OidParser parser(false);
printf("/***********************\n");
printf("Cert File Name: %s\n", fileName);
field.FieldValue = *subject;
field.FieldOid = CSSMOID_X509V1SubjectNameCStruct;
printCertField(field, parser, true);
printf(" ***********************/\n");
}
int main(int argc, char **argv)
{
CSSM_CL_HANDLE clHand; CSSM_DATA rawCert = {0, NULL};
uint32 numFields;
CSSM_HANDLE ResultsHandle = 0;
char baseName[255];
char blobName[255];
char *cp;
int rtn;
int nameLen;
CSSM_RETURN crtn;
CSSM_DATA_PTR value;
CSSM_KEY_PTR key;
uint32 keySize;
NSS_Certificate signedCert;
SecAsn1CoderRef coder;
if(argc != 2) {
printf("usage: %s certFile\n", argv[0]);
exit(1);
}
clHand = clStartup();
if(clHand == 0) {
printf("clStartup failure; aborting\n");
return 0;
}
unsigned len;
rtn = readFile(argv[1], &rawCert.Data, &len);
if(rtn) {
printf("Error %s reading file %s\n", strerror(rtn), argv[1]);
exit(1);
}
rawCert.Length = len;
nameLen = strlen(argv[1]);
memmove(baseName, argv[1], nameLen);
baseName[nameLen] = '\0';
cp = strchr(baseName, '.');
if(cp) {
*cp = '\0';
}
cp = strchr(baseName, ' ');
if(cp) {
*cp = '\0';
}
crtn = CSSM_CL_CertGetFirstFieldValue(
clHand,
&rawCert,
&CSSMOID_X509V1SubjectNameCStruct,
&ResultsHandle,
&numFields,
&value);
if(crtn) {
printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_X509V1SubjectNameCStruct)", crtn);
goto abort;
}
CSSM_CL_CertAbortQuery(clHand, ResultsHandle);
if(value == NULL) {
printf("Error extracting subject name\n");
goto abort;
}
printHeader(argv[1], value);
CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectNameCStruct, value);
crtn = CSSM_CL_CertGetFirstFieldValue(
clHand,
&rawCert,
&SUBJECT_NAME_OID,
&ResultsHandle,
&numFields,
&value);
if(crtn) {
printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_X509V1SubjectName)", crtn);
goto abort;
}
CSSM_CL_CertAbortQuery(clHand, ResultsHandle);
if(value == NULL) {
printf("Error extracting subject name\n");
goto abort;
}
sprintf(blobName, "%s_subject", baseName);
dumpDataBlob(blobName, value);
#if WRITE_NAME_FILE
writeFile(blobName, value->Data, (unsigned)value->Length);
#endif
CSSM_CL_FreeFieldValue(clHand, &SUBJECT_NAME_OID, value);
crtn = CSSM_CL_CertGetFirstFieldValue(
clHand,
&rawCert,
&CSSMOID_CSSMKeyStruct,
&ResultsHandle,
&numFields,
&value);
if(crtn) {
printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_CSSMKeyStruct)", crtn);
goto abort;
}
CSSM_CL_CertAbortQuery(clHand, ResultsHandle );
if(value == NULL) {
printf("Error extracting public key\n");
goto abort;
}
if(value->Length != sizeof(CSSM_KEY)) {
printf("CSSMOID_CSSMKeyStruct length error\n");
goto abort;
}
key = (CSSM_KEY_PTR)value->Data;
sprintf(blobName, "%s_pubKey", baseName);
dumpDataBlob(blobName, &key->KeyData);
keySize = key->KeyHeader.LogicalKeySizeInBits;
CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CSSMKeyStruct, value);
SecAsn1CoderCreate(&coder);
memset(&signedCert, 0, sizeof(signedCert));
if(SecAsn1DecodeData(coder, &rawCert, kSecAsn1SignedCertTemplate, &signedCert)) {
printf("***Error NSS-decoding certificate\n");
}
else {
sprintf(blobName, "%s_derIssuer", baseName);
dumpDataBlob(blobName, &signedCert.tbs.derIssuer);
}
printf("\n { &%s_subject, &%s_pubKey, %u },\n", baseName, baseName, (unsigned)keySize);
abort:
free(rawCert.Data);
if(clHand != 0) {
CSSM_ModuleDetach(clHand);
}
SecAsn1CoderRelease(coder);
return 0;
}