#include "cdsaUtils.h"
#include <Security/cssmerr.h>
#ifdef NDEBUG
#include <Security/globalizer.h>
ModuleNexus<Asn1ErrorClass> AsnNullError;
#endif
void SC_asnBitsToCssmData(
const AsnBits &bits,
CssmOwnedData &oData)
{
size_t len = (bits.BitLen() + 7) / 8;
oData.copy(reinterpret_cast<const uint8 *>(bits.BitOcts()), len);
}
void SC_decodeAsnBitsToCssmData(
const CssmData encodedBits,
CssmOwnedData &oData)
{
AsnBits decodedBits;
SC_decodeAsnObj(encodedBits, decodedBits);
size_t len = (decodedBits.BitLen() + 7) / 8;
oData.copy(reinterpret_cast<const uint8 *>(decodedBits.BitOcts()), len);
}
static int SC_BDecPDU(
AsnType &asnObj,
BUF_TYPE b,
AsnLen &bytesDecoded)
{
ENV_TYPE env;
bytesDecoded = 0;
try {
asnObj.BDec(b, bytesDecoded, env);
return !b.ReadError();
}
catch(...) {
return false;
}
}
static int SC_BEncPdu(
AsnType &asnObj,
BUF_TYPE b,
AsnLen &bytesEncoded)
{
bytesEncoded = asnObj.BEnc(b);
return !b.WriteError();
}
void SC_decodeAsnObj(
const CssmData &derEncoded,
AsnType &asnObj)
{
AsnBuf buf;
size_t len = (size_t)derEncoded.length();
buf.InstallData(reinterpret_cast<char *>(derEncoded.data()), len);
if(!SC_BDecPDU(asnObj, buf, len)) {
CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
}
}
void SC_encodeAsnObj(
AsnType &asnObj,
CssmOwnedData &derEncoded,
size_t maxEncodedSize)
{
CssmAutoData aData(derEncoded.allocator); aData.malloc(maxEncodedSize);
memset(aData.data(), 0, maxEncodedSize);
AsnBuf encBuf;
encBuf.Init(static_cast<char *>(aData.data()), maxEncodedSize);
encBuf.ResetInWriteRvsMode();
AsnLen encoded;
int rtn = SC_BEncPdu(asnObj, encBuf, encoded);
if(encoded > maxEncodedSize) {
CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
}
if(!rtn) {
CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
}
derEncoded.get().clear();
derEncoded.copy(encBuf.DataPtr(), encBuf.DataLen());
}
size_t SC_lengthOfLength(
size_t contentLen)
{
if(contentLen < 128) {
return 1;
}
else if(contentLen < 256) {
return 2;
}
else if(contentLen < 65536) {
return 3;
}
else if(contentLen < 16777126) {
return 4;
}
else {
return 5;
}
}
void SC_encodeLength(
size_t contentLen,
void *cp,
size_t lengthOfLength)
{
if(lengthOfLength == 0) {
lengthOfLength = SC_lengthOfLength(contentLen);
}
unsigned char *ucp = reinterpret_cast<unsigned char *>(cp);
if(lengthOfLength == 1) {
*ucp = contentLen;
return;
}
lengthOfLength--;
*ucp = (0x80 + lengthOfLength);
ucp += lengthOfLength;
for(size_t i=0; i<lengthOfLength; i++) {
*ucp-- = contentLen & 0xff;
contentLen >>= 8;
}
}
void SnaccExcep::throwMe(int err)
{
throw SnaccExcep(err);
}