pkinit_apple_utils.c [plain text]
#if APPLE_PKINIT
#include "pkinit_apple_utils.h"
#include "pkinit_asn1.h"
#include <sys/errno.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <ctype.h>
#include <Security/Security.h>
static CSSM_VERSION vers = {2, 0};
static const CSSM_GUID testGuid = { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
static void * cuAppMalloc (CSSM_SIZE size, void *allocRef) {
return( malloc(size) );
}
static void cuAppFree (void *mem_ptr, void *allocRef) {
free(mem_ptr);
return;
}
static void * cuAppRealloc (void *ptr, CSSM_SIZE size, void *allocRef) {
return( realloc( ptr, size ) );
}
static void * cuAppCalloc (uint32 num, CSSM_SIZE size, void *allocRef) {
return( calloc( num, size ) );
}
static CSSM_API_MEMORY_FUNCS memFuncs = {
cuAppMalloc,
cuAppFree,
cuAppRealloc,
cuAppCalloc,
NULL
};
static CSSM_BOOL cssmInitd = CSSM_FALSE;
static CSSM_BOOL cuCssmStartup()
{
CSSM_RETURN crtn;
CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE;
if(cssmInitd) {
return CSSM_TRUE;
}
crtn = CSSM_Init (&vers,
CSSM_PRIVILEGE_SCOPE_NONE,
&testGuid,
CSSM_KEY_HIERARCHY_NONE,
&pvcPolicy,
NULL );
if(crtn != CSSM_OK)
{
return CSSM_FALSE;
}
else {
cssmInitd = CSSM_TRUE;
return CSSM_TRUE;
}
}
CSSM_CL_HANDLE pkiClStartup(void)
{
CSSM_CL_HANDLE clHand;
CSSM_RETURN crtn;
if(cuCssmStartup() == CSSM_FALSE) {
return 0;
}
crtn = CSSM_ModuleLoad(&gGuidAppleX509CL,
CSSM_KEY_HIERARCHY_NONE,
NULL,
NULL);
if(crtn) {
return 0;
}
crtn = CSSM_ModuleAttach (&gGuidAppleX509CL,
&vers,
&memFuncs,
0,
CSSM_SERVICE_CL,
0,
CSSM_KEY_HIERARCHY_NONE,
NULL,
0,
NULL,
&clHand);
if(crtn) {
return 0;
}
else {
return clHand;
}
}
CSSM_RETURN pkiClDetachUnload(
CSSM_CL_HANDLE clHand)
{
CSSM_RETURN crtn = CSSM_ModuleDetach(clHand);
if(crtn) {
return crtn;
}
return CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL);
}
krb5_error_code pkiDataToInt(
const CSSM_DATA *cdata,
krb5_int32 *i)
{
krb5_ui_4 len;
krb5_int32 rtn = 0;
krb5_ui_4 dex;
uint8 *cp = NULL;
if((cdata->Length == 0) || (cdata->Data == NULL)) {
*i = 0;
return 0;
}
len = cdata->Length;
if(len > sizeof(krb5_int32)) {
return ASN1_BAD_LENGTH;
}
cp = cdata->Data;
for(dex=0; dex<len; dex++) {
rtn = (rtn << 8) | *cp++;
}
*i = rtn;
return 0;
}
krb5_error_code pkiIntToData(
krb5_int32 num,
CSSM_DATA *cdata,
SecAsn1CoderRef coder)
{
krb5_ui_4 unum = (krb5_ui_4)num;
uint32 len = 0;
uint8 *cp = NULL;
unsigned i;
if(unum < 0x100) {
len = 1;
}
else if(unum < 0x10000) {
len = 2;
}
else if(unum < 0x1000000) {
len = 3;
}
else {
len = 4;
}
if(SecAsn1AllocItem(coder, cdata, len)) {
return ENOMEM;
}
cp = &cdata->Data[len - 1];
for(i=0; i<len; i++) {
*cp-- = unum & 0xff;
unum >>= 8;
}
return 0;
}
krb5_error_code pkiDataToKrb5Data(
const void *data,
unsigned dataLen,
krb5_data *kd)
{
assert(data != NULL);
assert(kd != NULL);
kd->data = (char *)malloc(dataLen);
if(kd->data == NULL) {
return ENOMEM;
}
kd->length = dataLen;
memmove(kd->data, data, dataLen);
return 0;
}
krb5_error_code pkiCssmDataToKrb5Data(
const CSSM_DATA *cd,
krb5_data *kd)
{
assert(cd != NULL);
return pkiDataToKrb5Data(cd->Data, cd->Length, kd);
}
krb5_error_code pkiKrb5DataToCssm(
const krb5_data *kd,
CSSM_DATA *cd,
SecAsn1CoderRef coder)
{
assert((cd != NULL) && (kd != NULL));
if(SecAsn1AllocCopy(coder, kd->data, kd->length, cd)) {
return ENOMEM;
}
return 0;
}
krb5_error_code pkiCfDataToKrb5Data(
CFDataRef cfData,
krb5_data *kd)
{
return pkiDataToKrb5Data(CFDataGetBytePtr(cfData),
CFDataGetLength(cfData), kd);
}
krb5_boolean pkiCompareCssmData(
const CSSM_DATA *d1,
const CSSM_DATA *d2)
{
if((d1 == NULL) || (d2 == NULL)) {
return FALSE;
}
if(d1->Length != d2->Length) {
return FALSE;
}
if(memcmp(d1->Data, d2->Data, d1->Length)) {
return FALSE;
}
else {
return TRUE;
}
}
krb5_error_code pkiKrbTimestampToStr(
krb5_timestamp kts,
char **str)
{
char *outStr = NULL;
time_t gmt_time = kts;
struct tm *utc = gmtime(&gmt_time);
if (utc == NULL ||
utc->tm_year > 8099 || utc->tm_mon > 11 ||
utc->tm_mday > 31 || utc->tm_hour > 23 ||
utc->tm_min > 59 || utc->tm_sec > 59) {
return ASN1_BAD_GMTIME;
}
outStr = (char *)malloc(16);
if(outStr == NULL) {
return ENOMEM;
}
sprintf(outStr, "%04d%02d%02d%02d%02d%02dZ",
utc->tm_year + 1900, utc->tm_mon + 1,
utc->tm_mday, utc->tm_hour, utc->tm_min, utc->tm_sec);
*str = outStr;
return 0;
}
krb5_error_code pkiTimeStrToKrbTimestamp(
const char *str,
unsigned len,
krb5_timestamp *kts)
{
char szTemp[5];
unsigned x;
unsigned i;
char *cp;
struct tm tmp;
time_t t;
if(len != 15) {
return ASN1_BAD_LENGTH;
}
if((str == NULL) || (kts == NULL)) {
return KRB5_CRYPTO_INTERNAL;
}
cp = (char *)str;
memset(&tmp, 0, sizeof(tmp));
for(i=0; i<(len - 1); i++) {
if ( !(isdigit(cp[i])) ) {
return ASN1_BAD_TIMEFORMAT;
}
}
if(cp[len - 1] != 'Z' ) {
return ASN1_BAD_TIMEFORMAT;
}
szTemp[0] = *cp++;
szTemp[1] = *cp++;
szTemp[2] = *cp++;
szTemp[3] = *cp++;
szTemp[4] = '\0';
x = atoi( szTemp );
tmp.tm_year = x - 1900;
szTemp[0] = *cp++;
szTemp[1] = *cp++;
szTemp[2] = '\0';
x = atoi( szTemp );
if((x > 12) || (x <= 0)) {
return ASN1_BAD_TIMEFORMAT;
}
tmp.tm_mon = x - 1;
szTemp[0] = *cp++;
szTemp[1] = *cp++;
szTemp[2] = '\0';
x = atoi( szTemp );
if((x > 31) || (x <= 0)) {
return ASN1_BAD_TIMEFORMAT;
}
tmp.tm_mday = x;
szTemp[0] = *cp++;
szTemp[1] = *cp++;
szTemp[2] = '\0';
x = atoi( szTemp );
if((x > 23) || (x < 0)) {
return ASN1_BAD_TIMEFORMAT;
}
tmp.tm_hour = x;
szTemp[0] = *cp++;
szTemp[1] = *cp++;
szTemp[2] = '\0';
x = atoi( szTemp );
if((x > 59) || (x < 0)) {
return ASN1_BAD_TIMEFORMAT;
}
tmp.tm_min = x;
szTemp[0] = *cp++;
szTemp[1] = *cp++;
szTemp[2] = '\0';
x = atoi( szTemp );
if((x > 59) || (x < 0)) {
return ASN1_BAD_TIMEFORMAT;
}
tmp.tm_sec = x;
t = timegm(&tmp);
if(t == -1) {
return ASN1_BAD_TIMEFORMAT;
}
*kts = t;
return 0;
}
unsigned pkiNssArraySize(
const void **array)
{
unsigned count = 0;
if (array) {
while (*array++) {
count++;
}
}
return count;
}
#endif