#include "pkcs_7_8.h"
#include "AppleCSPUtils.h"
#include <Security/threading.h>
static Mutex snaccLock;
#include <Security/asn-incl.h>
#include <Security/sm_vdatypes.h>
#include <Security/sm_x501ud.h>
#include <Security/sm_x411ub.h>
#include <Security/sm_x411mtsas.h>
#include <Security/sm_x501if.h>
#include <Security/sm_x520sa.h>
#include <Security/sm_x509cmn.h>
#include <Security/sm_x509af.h>
#include <Security/sm_x509ce.h>
#include <Security/pkcs1oids.h>
#include <Security/pkcs9oids.h>
#include <Security/sm_cms.h>
#include <Security/sm_ess.h>
#include <Security/pkcs7.h>
#include <Security/pkcs8.h>
static void algAndModeToOid(
CSSM_ALGORITHMS alg,
CSSM_ENCRYPT_MODE mode,
AsnOid &oid) {
switch(alg) {
case CSSM_ALGID_DES:
case CSSM_ALGID_3DES_3KEY_EDE:
oid.ReSet(des_ede3_cbc_arc);
break;
case CSSM_ALGID_RC2:
switch(mode) {
case CSSM_ALGMODE_CBCPadIV8:
case CSSM_ALGMODE_CBC_IV8:
oid.ReSet(rc2_cbc_arc);
break;
default:
oid.ReSet(rc2_ecb_arc);
break;
}
break;
case CSSM_ALGID_RC4:
oid.ReSet(rc4_arc);
break;
case CSSM_ALGID_RC5:
if(mode == CSSM_ALGMODE_CBCPadIV8) {
oid.ReSet(rc5_CBCPad_arc);
}
else {
oid.ReSet(rc5CBC_arc);
}
break;
case CSSM_ALGID_DESX:
oid.ReSet(desx_CBC_arc);
break;
case CSSM_ALGID_RSA:
oid.ReSet(rsaEncryption_arc); break;
default:
errorLog2("algAndModeToOid: Unknown alg %d mode %d\n", (int)alg,
(int)mode);
CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
}
return;
}
#define PKCS7_BUFSIZE 128
void cspEncodePkcs7(
CSSM_ALGORITHMS alg, CSSM_ENCRYPT_MODE mode, const CssmData &encryptedBlob,
CssmData &encodedBlob, CssmAllocator &allocator)
{
AsnBuf buf;
char *b;
unsigned bLen;
EncryptedData1 ed;
EncryptedContentInfo1 *eci;
AlgorithmIdentifier *algId;
AsnLen len;
StLock<Mutex> _(snaccLock);
ed.version.Set(EncryptedDataInt::edVer0);
eci = ed.encryptedContentInfo = new EncryptedContentInfo1;
eci->contentType = encryptedData; algId = eci->contentEncryptionAlgorithm = new AlgorithmIdentifier;
algAndModeToOid(alg, mode, algId->algorithm);
eci->encryptedContent = new AsnOcts(
(char *)encryptedBlob.Data, (size_t)encryptedBlob.Length);
bLen = PKCS7_BUFSIZE + encryptedBlob.Length;
b = (char *)allocator.malloc(bLen);
buf.Init(b, bLen);
buf.ResetInWriteRvsMode();
len = ed.BEnc(buf);
setUpCssmData(encodedBlob, len, allocator);
memmove(encodedBlob.Data, buf.DataPtr(), len);
allocator.free(b);
}
void cspDecodePkcs7(
const CssmKey &wrappedKey, CssmData &decodedBlob, CSSM_KEYBLOB_FORMAT &format, CssmAllocator &allocator)
{
const CssmData &encodedBlob =
CssmData::overlay(wrappedKey.KeyData);
ENV_TYPE jbuf;
EncryptedData1 ed;
int rtn;
AsnBuf buf;
size_t len = (size_t)encodedBlob.Length;
StLock<Mutex> _(snaccLock);
buf.InstallData((char *)encodedBlob.Data, len);
try {
int i;
EncryptedContentInfo1 *eci;
ed.BDec(buf, len, jbuf);
i = ed.version;
if(i != EncryptedDataInt::edVer0) {
errorLog1("cspDecodePkcs7: bad edDec.version (%d)\n", i);
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
}
eci = ed.encryptedContentInfo;
if(!(eci->contentType == encryptedData)) {
errorLog0("cspDecodePkcs7: bad contentType\n");
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
}
setUpCssmData(decodedBlob,
eci->encryptedContent->Len(),
allocator);
memmove(decodedBlob.Data,
(char *)(*eci->encryptedContent),
eci->encryptedContent->Len());
}
catch(...) {
errorLog1("cspDecodePkcs7: BDec threw %d\n", rtn);
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
}
format = inferFormat(wrappedKey);
}
#define PKCS8_BUFSIZE 64
void cspEncodePkcs8(
CSSM_ALGORITHMS alg, CSSM_ENCRYPT_MODE mode, const CssmData &encryptedBlob,
CssmData &encodedBlob, CssmAllocator &allocator)
{
AsnBuf buf;
char *b;
unsigned bLen;
EncryptedPrivateKeyInfo epki;
AsnLen len;
StLock<Mutex> _(snaccLock);
epki.encryptionAlgorithm = new AlgorithmIdentifier;
algAndModeToOid(alg, mode, epki.encryptionAlgorithm->algorithm);
epki.encryptedKey.Set((char *)encryptedBlob.Data, encryptedBlob.Length);
bLen = PKCS8_BUFSIZE + encryptedBlob.Length;
b = (char *)allocator.malloc(bLen);
buf.Init(b, bLen);
buf.ResetInWriteRvsMode();
len = epki.BEnc(buf);
setUpCssmData(encodedBlob, len, allocator);
memmove(encodedBlob.Data, buf.DataPtr(), len);
allocator.free(b);
}
void cspDecodePkcs8(
const CssmKey &wrappedKey, CssmData &decodedBlob, CSSM_KEYBLOB_FORMAT &format, CssmAllocator &allocator)
{
const CssmData &encodedBlob =
CssmData::overlay(wrappedKey.KeyData);
ENV_TYPE jbuf;
EncryptedData1 ed;
int rtn;
AsnBuf buf;
size_t len = (size_t)encodedBlob.Length;
StLock<Mutex> _(snaccLock);
buf.InstallData((char *)encodedBlob.Data, len);
try {
EncryptedPrivateKeyInfo epki;
epki.BDec(buf, len, jbuf);
len = epki.encryptedKey.Len();
setUpCssmData(decodedBlob, len, allocator);
memmove(decodedBlob.Data,
(char *)(epki.encryptedKey),
len);
}
catch(...) {
errorLog1("cspDecodePkcs8: BDec threw %d\n", rtn);
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
}
format = inferFormat(wrappedKey);
}