+++ /dev/null
-/*
- * rsatool.c - RSA/DSA/ECDSA key pair generator, en/decrypt, sign/verify with file I/O
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <Security/cssm.h>
-#include "cspwrap.h"
-#include "common.h"
-#include <security_cdsa_utils/cuFileIo.h>
-
-/* For 3141770 - defined true when PR-3074739 merged to TOT Security */
-#define OPENSSL_ENABLE 1
-
-#define USAGE_NAME "noUsage"
-#define USAGE_NAME_LEN (strlen(USAGE_NAME))
-#define DEFAULT_KEY_SIZE_BITS 512
-
-typedef struct {
- CSSM_ALGORITHMS alg;
- uint32 keySizeInBits;
- CSSM_CSP_HANDLE cspHand;
- char *keyFileName;
- char *outKeyFileName; // for pub key convert
- char *plainFileName;
- char *sigFileName;
- char *cipherFileName;
- char *dsaParamFileIn;
- char *dsaParamFileOut;
- CSSM_BOOL swapKeyClass;
- CSSM_BOOL rawSign;
- CSSM_BOOL noPad;
- CSSM_BOOL quiet;
- CSSM_KEYBLOB_FORMAT pubKeyFormat; // FORMAT_NONE ==> default
- CSSM_KEYBLOB_FORMAT privKeyFormat; // FORMAT_NONE ==> default
- CSSM_KEYBLOB_FORMAT outPubKeyFormat;// FORMAT_NONE ==> default, for pub key convert
- CSSM_ALGORITHMS digestAlg; // optional digest alg for raw sign/verify
-} opParams;
-
-static void usage(char **argv)
-{
- printf("usage: %s op [options]\n", argv[0]);
- printf(" op:\n");
- printf(" g generate key pair\n");
- printf(" e encrypt\n");
- printf(" d decrypt\n");
- printf(" s sign\n");
- printf(" v verify\n");
- printf(" S SHA-1 digest\n");
- printf(" M MD5 digest\n");
- printf(" C convert public key format\n");
- printf(" options:\n");
- printf(" k=keyfileBase keys are keyFileBase_pub.der, "
- "keyFileBase_priv.der)\n");
- printf(" K=outputPublicKey\n");
- printf(" p=plainFile\n");
- printf(" c=cipherFile\n");
- printf(" s=sigfile\n");
- printf(" z=keySizeInBits (default %d)\n", DEFAULT_KEY_SIZE_BITS);
- printf(" w (swap key class)\n");
- printf(" r (raw sign/verify)\n");
- printf(" P (no padding)\n");
- printf(" d=digestAlg digestAlg: s(SHA1) 5(MD5) for raw signing\n");
- printf(" m=dsaParamFileIn\n");
- printf(" M=dsaParamFileOut (must specify one of dsaParamFile{In,Out}\n");
- printf(" b=[1xboOL] (pub key in PKCS1/X509/BSAFE/OpenSSH1/OpenSSH2/OpenSSL form)\n");
- printf(" RSA = {PKCS1,X509,OpenSSH1,OpenSSH2} default = PKCS1\n");
- printf(" DSA = {BSAFE,X509,OpenSSH2} default = X509\n");
- printf(" ECDSA = {X509, OpenSSL} default = X509\n");
- printf(" Note: RSA and DSA public keys in OpenSSL form are X509.\n");
- printf(" v=[18sbo] (priv key in PKCS1/PKCS8/OpenSSH/BSAFE/OpenSSL form)\n");
- printf(" RSA = {PKCS1,PKCS8,OpenSSH1} default = PKCS8\n");
- printf(" DSA = {BSAFE,OpenSSL,PKCS8} default = OpenSSL\n");
- printf(" ECDSA = {PKCS8,OpenSSL} default = OpenSSL}\n");
- printf(" Note: RSA private key in OpenSSL form is PKCS1.\n");
- printf(" B=[1xboO] output public key format\n");
- printf(" a=alg d=DSA, r=RSA, e=ECDSA; default = RSA\n");
- printf(" q(uiet)\n");
- exit(1);
-}
-
-/* NULL wrap a key to specified format. */
-static CSSM_RETURN nullWrapKey(CSSM_CSP_HANDLE cspHand,
- const CSSM_KEY *refKey,
- CSSM_KEYBLOB_FORMAT blobFormat,
- CSSM_KEY_PTR rawKey) // RETURNED
-{
- CSSM_CC_HANDLE ccHand;
- CSSM_RETURN crtn;
- CSSM_ACCESS_CREDENTIALS creds;
- CSSM_DATA descData = {0, 0};
-
- memset(rawKey, 0, sizeof(CSSM_KEY));
- memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
- crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
- CSSM_ALGID_NONE,
- CSSM_ALGMODE_NONE,
- &creds, // passPhrase
- NULL, // unwrappingKey
- NULL, // initVector
- CSSM_PADDING_NONE,
- 0, // Params
- &ccHand);
- if(crtn) {
- printError("cspWrapKey/CreateContext", crtn);
- return crtn;
- }
- if(blobFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) {
- /* only add this attribute if it's not the default */
- CSSM_ATTRIBUTE_TYPE attrType;
-
- switch(refKey->KeyHeader.KeyClass) {
- case CSSM_KEYCLASS_SESSION_KEY:
- attrType = CSSM_ATTRIBUTE_SYMMETRIC_KEY_FORMAT;
- break;
- case CSSM_KEYCLASS_PUBLIC_KEY:
- attrType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT;
- break;
- case CSSM_KEYCLASS_PRIVATE_KEY:
- attrType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT;
- break;
- default:
- printf("***Bogus KeyClass in nullWrapKey\n");
- return -1;
- }
- CSSM_CONTEXT_ATTRIBUTE attr;
- attr.AttributeType = attrType;
- attr.AttributeLength = sizeof(uint32);
- attr.Attribute.Uint32 = blobFormat;
- crtn = CSSM_UpdateContextAttributes(
- ccHand,
- 1,
- &attr);
- if(crtn) {
- printError("CSSM_UpdateContextAttributes", crtn);
- return crtn;
- }
- }
- crtn = CSSM_WrapKey(ccHand,
- &creds,
- refKey,
- &descData,
- rawKey);
- if(crtn != CSSM_OK) {
- printError("CSSM_WrapKey", crtn);
- }
- if(CSSM_DeleteContext(ccHand)) {
- printf("CSSM_DeleteContext failure\n");
- }
- return crtn;
-}
-
-/*
- * Sign/verify optional "no padding" context attr
- */
-static CSSM_RETURN sigSign(CSSM_CSP_HANDLE cspHand,
- uint32 algorithm, // CSSM_ALGID_FEE_MD5, etc.
- CSSM_KEY_PTR key, // private key
- const CSSM_DATA *text,
- CSSM_DATA_PTR sig,
- uint32 digestAlg, // optional for raw signing
- CSSM_BOOL noPad) // true --> add PADDING_NONE to context
-{
- CSSM_CC_HANDLE sigHand;
- CSSM_RETURN crtn;
-
- crtn = CSSM_CSP_CreateSignatureContext(cspHand,
- algorithm,
- NULL, // passPhrase
- key,
- &sigHand);
- if(crtn) {
- printError("CSSM_CSP_CreateSignatureContext", crtn);
- return crtn;
- }
- if(noPad) {
- crtn = AddContextAttribute(sigHand,
- CSSM_ATTRIBUTE_PADDING,
- sizeof(uint32),
- CAT_Uint32,
- NULL,
- CSSM_PADDING_NONE);
- if(crtn) {
- return crtn;
- }
- }
- crtn = CSSM_SignData(sigHand,
- text,
- 1,
- digestAlg,
- sig);
- if(crtn) {
- printError("CSSM_SignData", crtn);
- }
- CSSM_DeleteContext(sigHand);
- return crtn;
-}
-
-static CSSM_RETURN sigVerify(CSSM_CSP_HANDLE cspHand,
- uint32 algorithm, // CSSM_ALGID_FEE_MD5, etc.
- CSSM_KEY_PTR key, // public key
- const CSSM_DATA *text,
- const CSSM_DATA *sig,
- uint32 digestAlg, // optional for raw signing
- CSSM_BOOL noPad) // true --> add PADDING_NONE to context
-{
- CSSM_CC_HANDLE sigHand;
- CSSM_RETURN crtn;
-
- crtn = CSSM_CSP_CreateSignatureContext(cspHand,
- algorithm,
- NULL, // passPhrase
- key,
- &sigHand);
- if(crtn) {
- printError("CSSM_CSP_CreateSignatureContext", crtn);
- return crtn;
- }
- if(noPad) {
- crtn = AddContextAttribute(sigHand,
- CSSM_ATTRIBUTE_PADDING,
- sizeof(uint32),
- CAT_Uint32,
- NULL,
- CSSM_PADDING_NONE);
- if(crtn) {
- return crtn;
- }
- }
- crtn = CSSM_VerifyData(sigHand,
- text,
- 1,
- digestAlg,
- sig);
- if(crtn) {
- printError("CSSM_VerifyData", crtn);
- }
- CSSM_DeleteContext(sigHand);
- return crtn;
-}
-
-/*
- * Generate DSA key pair. Algorithm parameters are
- * either specified by caller via inParams, or are generated here
- * and returned to caller in outParams. Exactly one of (inParams,
- * outParams) must be non-NULL.
- */
-static CSSM_RETURN genDsaKeyPair(
- CSSM_CSP_HANDLE cspHand,
- const char *keyLabel,
- unsigned keyLabelLen,
- uint32 keySize, // in bits
- CSSM_KEY_PTR pubKey, // mallocd by caller
- CSSM_BOOL pubIsRef, // true - reference key, false - data
- uint32 pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc.
- CSSM_KEYBLOB_FORMAT pubFormat, // Optional. Some algorithms (currently, FEE)
- // provide for multiple key blob formats.
- // Specify 0 or CSSM_KEYBLOB_RAW_FORMAT_NONE
- // to get the default format.
- CSSM_KEY_PTR privKey, // mallocd by caller
- CSSM_BOOL privIsRef, // true - reference key, false - data
- uint32 privKeyUsage, // CSSM_KEYUSE_DECRYPT, etc.
- CSSM_KEYBLOB_FORMAT privFormat, // optional 0 ==> default
- const CSSM_DATA *inParams, // optional
- CSSM_DATA_PTR outParams) // optional, we malloc
-{
- CSSM_RETURN crtn;
- CSSM_CC_HANDLE ccHand;
- CSSM_DATA keyLabelData;
- uint32 pubAttr;
- uint32 privAttr;
- CSSM_RETURN ocrtn = CSSM_OK;
-
- /* Caller must specify either inParams or outParams, not both */
- if(inParams && outParams) {
- return CSSMERR_CSSM_INVALID_POINTER;
- }
- if(!inParams && !outParams) {
- return CSSMERR_CSSM_INVALID_POINTER;
- }
-
- keyLabelData.Data = (uint8 *)keyLabel,
- keyLabelData.Length = keyLabelLen;
- memset(pubKey, 0, sizeof(CSSM_KEY));
- memset(privKey, 0, sizeof(CSSM_KEY));
-
- crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
- CSSM_ALGID_DSA,
- keySize,
- NULL, // Seed
- NULL, // Salt
- NULL, // StartDate
- NULL, // EndDate
- inParams, // Params, may be NULL
- &ccHand);
- if(crtn) {
- printError("CSSM_CSP_CreateKeyGenContext", crtn);
- return crtn;
- }
- /* cook up attribute bits */
- if(pubIsRef) {
- pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
- }
- else {
- pubAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
- }
- if(privIsRef) {
- privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
- }
- else {
- privAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
- }
-
- if(outParams) {
- /* explicitly generate params and return them to caller */
- outParams->Data = NULL;
- outParams->Length = 0;
- crtn = CSSM_GenerateAlgorithmParams(ccHand,
- keySize, outParams);
- if(crtn) {
- printError("CSSM_GenerateAlgorithmParams", crtn);
- CSSM_DeleteContext(ccHand);
- return crtn;
- }
- }
-
- /* optional format specifiers */
- if(pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) {
- crtn = AddContextAttribute(ccHand,
- CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT,
- sizeof(uint32),
- CAT_Uint32,
- NULL,
- pubFormat);
- if(crtn) {
- printError("AddContextAttribute(CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn);
- return crtn;
- }
- }
- if(privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) {
- crtn = AddContextAttribute(ccHand,
- CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT,
- sizeof(uint32),
- CAT_Uint32,
- NULL,
- privFormat);
- if(crtn) {
- printError("AddContextAttribute(CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn);
- return crtn;
- }
- }
- crtn = CSSM_GenerateKeyPair(ccHand,
- pubKeyUsage,
- pubAttr,
- &keyLabelData,
- pubKey,
- privKeyUsage,
- privAttr,
- &keyLabelData, // same labels
- NULL, // CredAndAclEntry
- privKey);
- if(crtn) {
- printError("CSSM_GenerateKeyPair", crtn);
- ocrtn = crtn;
- }
- if(ccHand != 0) {
- crtn = CSSM_DeleteContext(ccHand);
- if(crtn) {
- printError("CSSM_DeleteContext", crtn);
- ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
- }
- }
- return ocrtn;
-}
-
-/*
- * Given keyFileBase, obtain name of public or private name. Output names
- * mallocd by caller.
- */
-#define KEY_FILE_NAME_MAX_LEN 256
-
-static void rtKeyFileName(
- const char *keyFileBase,
- CSSM_BOOL isPub,
- char *outFileName)
-{
- if(isPub) {
- sprintf(outFileName, "%s_pub.der", keyFileBase);
- }
- else {
- sprintf(outFileName, "%s_priv.der", keyFileBase);
- }
-}
-
-/*
- * Given keyFileBase and key type, init a CSSM_KEY.
- */
-static int rt_readKey(
- CSSM_CSP_HANDLE cspHand,
- const char *keyFileBase,
- CSSM_BOOL isPub,
- CSSM_ALGORITHMS alg,
- CSSM_KEYBLOB_FORMAT format, // FORMAT_NONE ==> default
- CSSM_KEY_PTR key)
-{
- char fileName[KEY_FILE_NAME_MAX_LEN];
- int irtn;
- CSSM_DATA_PTR keyData = &key->KeyData;
- CSSM_KEYHEADER_PTR hdr = &key->KeyHeader;
- CSSM_RETURN crtn;
- CSSM_KEY_SIZE keySize;
- unsigned len;
-
- memset(key, 0, sizeof(CSSM_KEY));
- rtKeyFileName(keyFileBase, isPub, fileName);
- irtn = readFile(fileName, &keyData->Data, &len);
- if(irtn) {
- printf("***error %d reading key file %s\n", irtn, fileName);
- return irtn;
- }
- keyData->Length = len;
- hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
- hdr->BlobType = CSSM_KEYBLOB_RAW;
- hdr->Format = format;
- hdr->AlgorithmId = alg;
- hdr->KeyClass = isPub ? CSSM_KEYCLASS_PUBLIC_KEY :
- CSSM_KEYCLASS_PRIVATE_KEY;
- hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
- hdr->KeyUsage = CSSM_KEYUSE_ANY;
-
- /* ask the CSP for key size */
- crtn = CSSM_QueryKeySizeInBits(cspHand, 0, key, &keySize);
- if(crtn) {
- printError("CSSM_QueryKeySizeInBits", crtn);
- return 1;
- }
- hdr->LogicalKeySizeInBits = keySize.LogicalKeySizeInBits;
- return 0;
-}
-
-static int rt_generate(opParams *op)
-{
- CSSM_RETURN crtn;
- CSSM_KEY pubKey;
- CSSM_KEY privKey;
- char fileName[KEY_FILE_NAME_MAX_LEN];
- int irtn;
- CSSM_DATA paramIn = {0, NULL};
- CSSM_DATA paramOut = {0, NULL};
- CSSM_DATA_PTR paramInPtr = NULL;
- CSSM_DATA_PTR paramOutPtr = NULL;
-
- if(op->keyFileName == NULL) {
- printf("***Need a keyFileName to generate key pair.\n");
- return 1;
- }
- memset(&pubKey, 0, sizeof(CSSM_KEY));
- memset(&privKey, 0, sizeof(CSSM_KEY));
-
- if(op->alg == CSSM_ALGID_DSA) {
- /* must specify either inParams or outParams, not both */
- if(op->dsaParamFileIn && op->dsaParamFileOut) {
- printf("***DSA key generation requires one parameter file spec.\n");
- return 1;
- }
- if(!op->dsaParamFileIn && !op->dsaParamFileOut) {
- printf("***DSA key generation requires one parameter file spec.\n");
- return 1;
- }
- if(op->dsaParamFileIn) {
- /* caller-specified params */
- unsigned len;
- irtn = readFile(op->dsaParamFileIn, ¶mIn.Data, &len);
- if(irtn) {
- printf("***Error reading DSA params from %s. Aborting.\n",
- op->dsaParamFileIn);
- }
- paramIn.Length = len;
- paramInPtr = ¶mIn;
- }
- else {
- /* generate params --> paramOut */
- paramOutPtr = ¶mOut;
- }
- crtn = genDsaKeyPair(op->cspHand,
- USAGE_NAME,
- USAGE_NAME_LEN,
- op->keySizeInBits,
- &pubKey,
- CSSM_FALSE, // not ref
- CSSM_KEYUSE_VERIFY, // not really important
- op->pubKeyFormat,
- &privKey,
- CSSM_FALSE, // not ref
- CSSM_KEYUSE_SIGN,
- op->privKeyFormat,
- paramInPtr,
- paramOutPtr);
- if(crtn) {
- return 1;
- }
- if(paramOutPtr) {
- irtn = writeFile(op->dsaParamFileOut, paramOut.Data, paramOut.Length);
- if(irtn) {
- printf("***Error writing DSA params to %s. Aborting.\n",
- op->dsaParamFileOut);
- return 1;
- }
- if(!op->quiet) {
- printf("...wrote %lu bytes to %s\n", paramOut.Length,
- op->dsaParamFileOut);
- }
- CSSM_FREE(paramOut.Data);
- }
- else {
- /* mallocd by readFile() */
- free(paramIn.Data);
- }
- }
- else {
- /* RSA, ECDSA */
- crtn = cspGenKeyPair(op->cspHand,
- op->alg,
- USAGE_NAME,
- USAGE_NAME_LEN,
- op->keySizeInBits,
- &pubKey,
- CSSM_FALSE, // not ref
- CSSM_KEYUSE_VERIFY, // not really important
- op->pubKeyFormat,
- &privKey,
- CSSM_FALSE, // not ref
- CSSM_KEYUSE_SIGN,
- op->privKeyFormat,
- CSSM_FALSE); // genSeed, not used here
- if(crtn) {
- return 1;
- }
- }
-
- /* write the blobs */
- rtKeyFileName(op->keyFileName, CSSM_TRUE, fileName);
- irtn = writeFile(fileName, pubKey.KeyData.Data, pubKey.KeyData.Length);
- if(irtn) {
- printf("***Error %d writing to %s\n", irtn, fileName);
- return irtn;
- }
- if(!op->quiet) {
- printf("...wrote %lu bytes to %s\n", pubKey.KeyData.Length, fileName);
- }
- rtKeyFileName(op->keyFileName, CSSM_FALSE, fileName);
- irtn = writeFile(fileName, privKey.KeyData.Data, privKey.KeyData.Length);
- if(irtn) {
- printf("***Error %d writing to %s\n", irtn, fileName);
- return irtn;
- }
- if(!op->quiet) {
- printf("...wrote %lu bytes to %s\n", privKey.KeyData.Length, fileName);
- }
- cspFreeKey(op->cspHand, &pubKey);
- cspFreeKey(op->cspHand, &privKey);
- return 0;
-}
-
-/* encrypt using public key */
-static int rt_encrypt(opParams *op)
-{
- CSSM_KEY pubKey;
- int irtn;
- CSSM_DATA ptext;
- CSSM_DATA ctext;
- CSSM_RETURN crtn;
- CSSM_BOOL isPub;
- CSSM_ENCRYPT_MODE mode = CSSM_ALGMODE_NONE;
- CSSM_KEYBLOB_FORMAT format = op->pubKeyFormat;
- unsigned len;
-
- if(op->keyFileName == NULL) {
- printf("***Need a keyFileName to encrypt.\n");
- return 1;
- }
- if((op->plainFileName == NULL) || (op->cipherFileName == NULL)) {
- printf("***Need plainFileName and cipherFileName to encrypt.\n");
- return 1;
- }
- if(op->swapKeyClass) {
- isPub = CSSM_FALSE;
- mode = CSSM_ALGMODE_PRIVATE_KEY;
- format = op->privKeyFormat;
- }
- else {
- isPub = CSSM_TRUE;
- }
- irtn = rt_readKey(op->cspHand, op->keyFileName, isPub, op->alg,
- format, &pubKey);
- if(irtn) {
- return irtn;
- }
- irtn = readFile(op->plainFileName, &ptext.Data, &len);
- if(irtn) {
- printf("***Error reading %s\n", op->plainFileName);
- return irtn;
- }
- ptext.Length = len;
- ctext.Data = NULL;
- ctext.Length = 0;
-
- crtn = cspEncrypt(op->cspHand,
- op->alg,
- mode,
- op->noPad ? CSSM_PADDING_NONE : CSSM_PADDING_PKCS1,
- &pubKey,
- NULL,
- 0, // effectiveKeySize
- 0, // rounds
- NULL, // initVector
- &ptext,
- &ctext,
- CSSM_FALSE); // mallocCtext
- if(crtn) {
- printError("cspEncrypt", crtn);
- return 1;
- }
- irtn = writeFile(op->cipherFileName, ctext.Data, ctext.Length);
- if(irtn) {
- printf("***Error writing %s\n", op->cipherFileName);
- }
- else {
- if(!op->quiet) {
- printf("...wrote %lu bytes to %s\n", ctext.Length, op->cipherFileName);
- }
- }
-
- free(pubKey.KeyData.Data); // allocd by rt_readKey --> readFile
- free(ptext.Data); // allocd by readFile
- appFreeCssmData(&ctext, CSSM_FALSE); // by CSP
- return irtn;
-}
-
-/* decrypt using private key */
-static int rt_decrypt(opParams *op)
-{
- CSSM_KEY privKey;
- int irtn;
- CSSM_DATA ptext;
- CSSM_DATA ctext;
- CSSM_RETURN crtn;
- CSSM_BOOL isPub;
- CSSM_ENCRYPT_MODE mode = CSSM_ALGMODE_NONE;
- CSSM_KEYBLOB_FORMAT format = op->privKeyFormat;
- unsigned len;
-
- if(op->keyFileName == NULL) {
- printf("***Need a keyFileName to decrypt.\n");
- return 1;
- }
- if((op->plainFileName == NULL) || (op->cipherFileName == NULL)) {
- printf("***Need plainFileName and cipherFileName to decrypt.\n");
- return 1;
- }
- if(op->swapKeyClass) {
- isPub = CSSM_TRUE;
- mode = CSSM_ALGMODE_PUBLIC_KEY;
- format = op->pubKeyFormat;
- }
- else {
- isPub = CSSM_FALSE;
- }
- irtn = rt_readKey(op->cspHand, op->keyFileName, isPub, op->alg,
- format, &privKey);
- if(irtn) {
- return irtn;
- }
- irtn = readFile(op->cipherFileName, &ctext.Data, &len);
- if(irtn) {
- printf("***Error reading %s\n", op->cipherFileName);
- return irtn;
- }
- ctext.Length = len;
- ptext.Data = NULL;
- ptext.Length = 0;
-
- crtn = cspDecrypt(op->cspHand,
- op->alg,
- mode,
- op->noPad ? CSSM_PADDING_NONE : CSSM_PADDING_PKCS1,
- &privKey,
- NULL,
- 0, // effectiveKeySize
- 0, // rounds
- NULL, // initVector
- &ctext,
- &ptext,
- CSSM_FALSE); // mallocCtext
- if(crtn) {
- return 1;
- }
- irtn = writeFile(op->plainFileName, ptext.Data, ptext.Length);
- if(irtn) {
- printf("***Error writing %s\n", op->cipherFileName);
- }
- else {
- if(!op->quiet) {
- printf("...wrote %lu bytes to %s\n", ptext.Length, op->plainFileName);
- }
- }
- free(privKey.KeyData.Data); // allocd by rt_readKey --> readFile
- free(ctext.Data); // allocd by readFile
- appFreeCssmData(&ptext, CSSM_FALSE); // by CSP
- return irtn;
-}
-
-static int rt_sign(opParams *op)
-{
- CSSM_KEY privKey;
- int irtn;
- CSSM_DATA ptext;
- CSSM_DATA sig;
- CSSM_RETURN crtn;
- CSSM_ALGORITHMS alg;
- unsigned len;
-
- if(op->keyFileName == NULL) {
- printf("***Need a keyFileName to sign.\n");
- return 1;
- }
- if((op->plainFileName == NULL) || (op->sigFileName == NULL)) {
- printf("***Need plainFileName and sigFileName to sign.\n");
- return 1;
- }
- irtn = rt_readKey(op->cspHand, op->keyFileName, CSSM_FALSE, op->alg,
- op->privKeyFormat, &privKey);
- if(irtn) {
- return irtn;
- }
- irtn = readFile(op->plainFileName, &ptext.Data, &len);
- if(irtn) {
- printf("***Error reading %s\n", op->plainFileName);
- return irtn;
- }
- ptext.Length = len;
- sig.Data = NULL;
- sig.Length = 0;
- switch(op->alg) {
- case CSSM_ALGID_RSA:
- if(op->rawSign) {
- alg = CSSM_ALGID_RSA;
- }
- else {
- alg = CSSM_ALGID_SHA1WithRSA;
- }
- break;
- case CSSM_ALGID_DSA:
- alg = CSSM_ALGID_SHA1WithDSA;
- break;
- case CSSM_ALGID_ECDSA:
- if(op->rawSign) {
- alg = CSSM_ALGID_ECDSA;
- }
- else {
- alg = CSSM_ALGID_SHA1WithECDSA;
- }
- break;
- default:
- printf("Hey! Try another alg!\n");
- exit(1);
- }
- crtn = sigSign(op->cspHand,
- alg,
- &privKey,
- &ptext,
- &sig,
- op->digestAlg,
- op->noPad);
- if(crtn) {
- printError("cspSign", crtn);
- return 1;
- }
- irtn = writeFile(op->sigFileName, sig.Data, sig.Length);
- if(irtn) {
- printf("***Error writing %s\n", op->sigFileName);
- }
- else if(!op->quiet) {
- printf("...wrote %lu bytes to %s\n", sig.Length, op->sigFileName);
- }
- free(privKey.KeyData.Data); // allocd by rt_readKey --> readFile
- free(ptext.Data); // allocd by readFile
- appFreeCssmData(&sig, CSSM_FALSE); // by CSP
- return irtn;
-}
-
-static int rt_verify(opParams *op)
-{
- CSSM_KEY pubKey;
- int irtn;
- CSSM_DATA ptext;
- CSSM_DATA sig;
- CSSM_RETURN crtn;
- CSSM_ALGORITHMS alg;
- unsigned len;
-
- if(op->keyFileName == NULL) {
- printf("***Need a keyFileName to verify.\n");
- return 1;
- }
- if((op->plainFileName == NULL) || (op->sigFileName == NULL)) {
- printf("***Need plainFileName and sigFileName to verify.\n");
- return 1;
- }
- irtn = rt_readKey(op->cspHand, op->keyFileName, CSSM_TRUE, op->alg,
- op->pubKeyFormat, &pubKey);
- if(irtn) {
- return irtn;
- }
- irtn = readFile(op->plainFileName, &ptext.Data, &len);
- if(irtn) {
- printf("***Error reading %s\n", op->plainFileName);
- return irtn;
- }
- ptext.Length = len;
- irtn = readFile(op->sigFileName, &sig.Data, (unsigned *)&sig.Length);
- if(irtn) {
- printf("***Error reading %s\n", op->sigFileName);
- return irtn;
- }
- switch(op->alg) {
- case CSSM_ALGID_RSA:
- if(op->rawSign) {
- alg = CSSM_ALGID_RSA;
- }
- else {
- alg = CSSM_ALGID_SHA1WithRSA;
- }
- break;
- case CSSM_ALGID_DSA:
- alg = CSSM_ALGID_SHA1WithDSA;
- break;
- case CSSM_ALGID_ECDSA:
- if(op->rawSign) {
- alg = CSSM_ALGID_ECDSA;
- }
- else {
- alg = CSSM_ALGID_SHA1WithECDSA;
- }
- break;
- default:
- printf("Hey! Try another alg!\n");
- exit(1);
- }
- crtn = sigVerify(op->cspHand,
- alg,
- &pubKey,
- &ptext,
- &sig,
- op->digestAlg,
- op->noPad);
- if(crtn) {
- printError("sigVerify", crtn);
- irtn = 1;
- }
- else if(!op->quiet){
- printf("...signature verifies OK\n");
- irtn = 0;
- }
- free(pubKey.KeyData.Data); // allocd by rt_readKey --> readFile
- free(ptext.Data); // allocd by readFile
- free(sig.Data); // ditto
- return irtn;
-}
-
-static int rt_digest(opParams *op)
-{
- int irtn;
- CSSM_DATA ptext;
- CSSM_DATA digest = {0, NULL};
- CSSM_RETURN crtn;
- unsigned len;
-
- if((op->plainFileName == NULL) || (op->sigFileName == NULL)) {
- printf("***Need plainFileName and sigFileName to digest.\n");
- return 1;
- }
- irtn = readFile(op->plainFileName, &ptext.Data, &len);
- if(irtn) {
- printf("***Error reading %s\n", op->plainFileName);
- return irtn;
- }
- ptext.Length = len;
- crtn = cspDigest(op->cspHand,
- op->alg,
- CSSM_FALSE, // mallocDigest - let CSP do it
- &ptext,
- &digest);
- if(crtn) {
- printError("cspDigest", crtn);
- return 1;
- }
- irtn = writeFile(op->sigFileName, digest.Data, digest.Length);
- if(irtn) {
- printf("***Error writing %s\n", op->sigFileName);
- }
- else if(!op->quiet){
- printf("...wrote %lu bytes to %s\n", digest.Length, op->sigFileName);
- }
- free(ptext.Data); // allocd by readFile
- appFreeCssmData(&digest, CSSM_FALSE); // by CSP
- return irtn;
-}
-
-static int rt_convertPubKey(opParams *op)
-{
- CSSM_RETURN crtn;
- int irtn;
- CSSM_KEY pubKeyIn;
- CSSM_KEY pubKeyOut;
- CSSM_KEY refKey;
- char fileName[KEY_FILE_NAME_MAX_LEN];
-
- if((op->keyFileName == NULL) || (op->outKeyFileName == NULL)) {
- printf("***I need input and output key file names for public key concersion.\n");
- return 1;
- }
- irtn = rt_readKey(op->cspHand, op->keyFileName, CSSM_TRUE, op->alg,
- op->pubKeyFormat, &pubKeyIn);
- if(irtn) {
- return irtn;
- }
- crtn = cspRawKeyToRef(op->cspHand, &pubKeyIn, &refKey);
- if(crtn) {
- printf("***Error on NULL unwrap of %s\n", op->keyFileName);
- return -1;
- }
- crtn = nullWrapKey(op->cspHand, &refKey, op->outPubKeyFormat, &pubKeyOut);
- if(crtn) {
- printf("***Error on NULL wrap\n");
- return 1;
- }
-
- /* write the blobs */
- rtKeyFileName(op->outKeyFileName, CSSM_TRUE, fileName);
- irtn = writeFile(fileName, pubKeyOut.KeyData.Data, pubKeyOut.KeyData.Length);
- if(irtn) {
- printf("***Error %d writing to %s\n", irtn, fileName);
- return irtn;
- }
- if(!op->quiet) {
- printf("...wrote %lu bytes to %s\n", pubKeyOut.KeyData.Length, fileName);
- }
- cspFreeKey(op->cspHand, &pubKeyOut);
- free(pubKeyIn.KeyData.Data);
- cspFreeKey(op->cspHand, &refKey);
- return 0;
-}
-
-/* parse public key format character */
-static CSSM_KEYBLOB_FORMAT parsePubKeyFormat(char c, char **argv)
-{
- switch(c) {
- case '1':
- return CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
- case 'x':
- return CSSM_KEYBLOB_RAW_FORMAT_X509;
- case 'b':
- return CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
- case 'o':
- return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH;
- case 'O':
- return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2;
- case 'L':
- /* This is the "parse a private+public key as public only" option */
- return CSSM_KEYBLOB_RAW_FORMAT_OPENSSL;
- default:
- usage(argv);
- }
- /* not reached */
- return -1;
-}
-
-int main(int argc, char **argv)
-{
- int arg;
- char *argp;
- int rtn;
- opParams op;
-
- if(argc < 2) {
- usage(argv);
- }
- memset(&op, 0, sizeof(opParams));
- op.keySizeInBits = DEFAULT_KEY_SIZE_BITS;
- op.alg = CSSM_ALGID_RSA;
- op.swapKeyClass = CSSM_FALSE;
- op.rawSign = CSSM_FALSE;
- op.noPad = CSSM_FALSE;
-
- for(arg=2; arg<argc; arg++) {
- argp = argv[arg];
- switch(argp[0]) {
- case 'a':
- if(argp[1] != '=') {
- usage(argv);
- }
- switch(argp[2]) {
- case 'r':
- op.alg = CSSM_ALGID_RSA;
- break;
- case 'd':
- op.alg = CSSM_ALGID_DSA;
- break;
- case 'e':
- op.alg = CSSM_ALGID_ECDSA;
- break;
- default:
- usage(argv);
- }
- break;
- case 'z':
- op.keySizeInBits = atoi(&argp[2]);
- break;
- case 'k':
- op.keyFileName = &argp[2];
- break;
- case 'K':
- op.outKeyFileName = &argp[2];
- break;
- case 'p':
- op.plainFileName = &argp[2];
- break;
- case 'c':
- op.cipherFileName = &argp[2];
- break;
- case 's':
- op.sigFileName = &argp[2];
- break;
- case 'w':
- op.swapKeyClass = CSSM_TRUE;
- break;
- case 'r':
- op.rawSign = CSSM_TRUE;
- break;
- case 'P':
- op.noPad = CSSM_TRUE;
- break;
- case 'm':
- op.dsaParamFileIn = &argp[2];
- break;
- case 'M':
- op.dsaParamFileOut = &argp[2];
- break;
- case 'q':
- op.quiet = CSSM_TRUE;
- break;
- case 'b':
- if(argp[1] != '=') {
- usage(argv);
- }
- op.pubKeyFormat = parsePubKeyFormat(argp[2], argv);
- break;
- case 'B':
- if(argp[1] != '=') {
- usage(argv);
- }
- op.outPubKeyFormat = parsePubKeyFormat(argp[2], argv);
- break;
- case 'v':
- if(argp[1] != '=') {
- usage(argv);
- }
- switch(argp[2]) {
- case '1':
- op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
- break;
- case '8':
- op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- break;
- case 's':
- op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSH;
- break;
- case 'b':
- op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
- break;
- #if OPENSSL_ENABLE
- case 'o':
- op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL;
- break;
- #endif
- default:
- usage(argv);
- }
- break;
- case 'd':
- if(argp[1] != '=') {
- usage(argv);
- }
- switch(argp[2]) {
- case 's':
- op.digestAlg = CSSM_ALGID_SHA1;
- break;
- case '5':
- op.digestAlg = CSSM_ALGID_MD5;
- break;
- default:
- usage(argv);
- }
- break;
- case 'h':
- default:
- usage(argv);
- }
- }
- op.cspHand = cspDlDbStartup(CSSM_TRUE, NULL);
- if(op.cspHand == 0) {
- exit(1);
- }
-
- /* specify blob formats if user didn't */
- if(op.pubKeyFormat == CSSM_KEYBLOB_RAW_FORMAT_NONE) {
- switch(op.alg) {
- case CSSM_ALGID_RSA:
- op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
- break;
- case CSSM_ALGID_DSA:
- case CSSM_ALGID_ECDSA:
- op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_X509;
- break;
- default:
- printf("BRRZAP!\n");
- exit(1);
- }
- }
- if(op.privKeyFormat == CSSM_KEYBLOB_RAW_FORMAT_NONE) {
- switch(op.alg) {
- case CSSM_ALGID_RSA:
- op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- break;
- case CSSM_ALGID_DSA:
- op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
- break;
- case CSSM_ALGID_ECDSA:
- op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL;
- break;
- default:
- printf("BRRZAP!\n");
- exit(1);
- }
- }
- switch(argv[1][0]) {
- case 'g':
- rtn = rt_generate(&op);
- break;
- case 'e':
- rtn = rt_encrypt(&op);
- break;
- case 'd':
- rtn = rt_decrypt(&op);
- break;
- case 's':
- rtn = rt_sign(&op);
- break;
- case 'v':
- rtn = rt_verify(&op);
- break;
- case 'S':
- op.alg = CSSM_ALGID_SHA1;
- rtn = rt_digest(&op);
- break;
- case 'M':
- op.alg = CSSM_ALGID_MD5;
- rtn = rt_digest(&op);
- break;
- case 'C':
- rtn = rt_convertPubKey(&op);
- break;
- default:
- usage(argv);
- exit(1); // fool the compiler
- }
- CSSM_ModuleDetach(op.cspHand);
- return rtn;
-}