#include "CertBuilder.h"
#include <Security/cssmerr.h>
#include <Security/utilities.h>
#include "cldebugging.h"
#define BUF_ENC_EXTRA 64
void NameBuilder::addATDV(
const AsnOid &type, const char *value, size_t valueLen,
DirectoryString::ChoiceIdEnum stringType,
bool primaryDistinguished)
{
if(rDNSequence == NULL) {
rDNSequence = new RDNSequence;
choiceId = rDNSequenceCid; }
RelativeDistinguishedName *rdn = rDNSequence->Append();
AttributeTypeAndDistinguishedValue *atdv = rdn->Append();
atdv->type = type;
if(!primaryDistinguished) {
atdv->primaryDistinguished = new AsnBool(primaryDistinguished);
}
DirectoryString dirStr;
dirStr.choiceId = stringType;
switch(stringType) {
case DirectoryString::teletexStringCid:
dirStr.teletexString = new TeletexString(value, valueLen);
break;
case DirectoryString::printableStringCid:
dirStr.printableString = new PrintableString(value, valueLen);
break;
case DirectoryString::universalStringCid:
dirStr.universalString = new UniversalString(value, valueLen);
break;
case DirectoryString::bmpStringCid:
dirStr.bmpString = new BMPString(value, valueLen);
break;
case DirectoryString::utf8StringCid:
dirStr.utf8String = new UTF8String(value, valueLen);
break;
}
size_t bufLen = valueLen + BUF_ENC_EXTRA;
char *buf = (char *)calloc(1, bufLen);
if(buf == NULL) {
CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
}
AsnBuf abuf;
abuf.Init(buf, bufLen);
abuf.ResetInWriteRvsMode();
AsnLen bytesEnc;
#if SNACC_ENABLE_PDU
dirStr.BEncPdu(abuf, bytesEnc);
if(bytesEnc > bufLen)
#else
bytesEnc = dirStr.BEnc(abuf);
if(abuf.WriteError() || (bytesEnc > bufLen))
#endif
{
#ifndef NDEBUG
printf("Whoops! Buffer overflow\n");
#endif
}
atdv->value.value = new CSM_Buffer(abuf.DataPtr(), abuf.DataLen());
free(buf);
}
void NameBuilder::addX509Name (
const CSSM_X509_NAME *x509Name)
{
for(unsigned rdnDex=0; rdnDex<x509Name->numberOfRDNs; rdnDex++) {
CSSM_X509_RDN_PTR rdn = &x509Name->RelativeDistinguishedName[rdnDex];
if(rdn->numberOfPairs != 1) {
errorLog0("setField_RDN: only one a/v pair per RDN supported\n");
CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
}
CSSM_X509_TYPE_VALUE_PAIR_PTR atv = rdn->AttributeTypeAndValue;
AsnOid oid;
oid.Set(reinterpret_cast<char *>(atv->type.Data), atv->type.Length);
DirectoryString::ChoiceIdEnum stringType;
switch(atv->valueType) {
case BER_TAG_T61_STRING:
stringType = DirectoryString::teletexStringCid;
break;
case BER_TAG_PRINTABLE_STRING:
stringType = DirectoryString::printableStringCid;
break;
case BER_TAG_PKIX_UNIVERSAL_STRING:
stringType = DirectoryString::universalStringCid;
break;
case BER_TAG_PKIX_BMP_STRING:
stringType = DirectoryString::bmpStringCid;
break;
case BER_TAG_PKIX_UTF8_STRING:
stringType = DirectoryString::utf8StringCid;
break;
default:
errorLog1("setField_RDN: illegal tag(%d)\n", atv->valueType);
CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER);
}
addATDV(oid,
reinterpret_cast<char *>(atv->value.Data),
atv->value.Length,
stringType);
}
}
OidBuilder::OidBuilder(const CSSM_OID &coid)
{
oid = Asn1Alloc (coid.Length);
memcpy(oid, coid.Data, coid.Length);
octetLen = coid.Length;
}