#include "spnegoBlob.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "spnegoKrb.h"
#include <security_cdsa_utils/cuEnc64.h>
#include <Security/SecAsn1Coder.h>
#include "spnegoDER.h"
#define PA_CHUNK_SIZE 1024
static void **nssNullArray(
SecAsn1CoderRef coder,
uint32 num)
{
unsigned len = (num + 1) * sizeof(void *);
void **p = (void **)SecAsn1Malloc(coder, len);
memset(p, 0, len);
return p;
}
int spnegoCreateInit(
const unsigned char *gssBlob,
unsigned gssBlobLen,
unsigned char **spnegoBlob, unsigned *spnegoBlobLen) {
SpnegoNegTokenInitGss negInit;
SecAsn1CoderRef coder;
if(SecAsn1CoderCreate(&coder)) {
return -1;
}
memset(&negInit, 0, sizeof(negInit));
negInit.oid = CSSMOID_SPNEGO;
negInit.token.mechTypeList = (CSSM_OID **)nssNullArray(coder, 2);
negInit.token.mechTypeList[0] = (CSSM_OID *)&CSSMOID_KERB_V5_LEGACY;
negInit.token.mechTypeList[1] = (CSSM_OID *)&CSSMOID_KERB_V5;
CSSM_DATA gssData;
if(gssBlob) {
gssData.Data = (uint8 *)gssBlob;
gssData.Length = gssBlobLen;
negInit.token.mechToken = &gssData;
}
CSSM_DATA res = {0, NULL};
OSStatus ortn = SecAsn1EncodeItem(coder, &negInit,
SpnegoNegTokenInitGssTemplate, &res);
if(ortn) {
SecAsn1CoderRelease(coder);
return -1;
}
*spnegoBlob = (unsigned char *)malloc(res.Length);
memmove(*spnegoBlob, res.Data, res.Length);
*spnegoBlobLen = res.Length;
SecAsn1CoderRelease(coder);
return 0;
}
int spnegoTokenInitFromPrincipal(
const char *inHostname,
const char *inServiceType,
char **spnegoBlob, unsigned *spnegoBlobLen) {
unsigned char *rawBlob = NULL;
unsigned rawBlobLen = 0;
unsigned char *tkt = NULL;
unsigned tktLen = 0;
int ourRtn = 0;
if(inHostname && inServiceType) {
krb5_error_code kerr = GetSvcTicketForHost(inHostname, inServiceType, &tktLen, &tkt);
if(kerr) {
return -1;
}
}
ourRtn = spnegoCreateInit(tkt, tktLen, &rawBlob, &rawBlobLen);
if(ourRtn) {
if (tkt) free(tkt);
return ourRtn;
}
*spnegoBlob = (char *)rawBlob;
*spnegoBlobLen = rawBlobLen;
if(tkt) {
free(tkt);
}
return ourRtn;
}