rl.c 2.82 KB
#include "common.h"
#include <PR/os_bbsa.h>

#define LAUNCH_CRLS 3

#define SARL_NO_FILE 1

/* 16 KB crl file (crl.sys) */
static u8 gRlBuf[CRLBUF_SIZE] ALIGN_DCACHE;

static int gNumRls = 0;

static char* getServerNameStr(char *in)
{
    int indx=strlen(in)-1;
    while(indx>0){
        if(in[indx--]=='-')
            return &in[indx+2];
    }
    return NULL;
}

static int fillCrlBundle(BbCrlHead *rl,BbCrlBundle *rlBundle)
{
    char *serverName;

    rlBundle->head = rl;
    rlBundle->list = (BbServerName *)(((u8 *)rl) + sizeof(BbCrlHead));
    serverName = getServerNameStr(rl->issuer);
    if(serverName==NULL){
        if(strcmp("Root",rl->issuer)==0)
            rlBundle->certChain[0]=NULL;
        else
            /* bad issuer string */
            return SARL_ERR;
    } else{
        if(osBbSaCertCreateChain(serverName,rlBundle->certChain)<0)
            /* couldn't construct cert chain */
            return SARL_ERR;
    }
    
    return BB_SYSAPP_PASS;
}

int osBbSaRlInit()
{
    OSBbStatBuf fsStat;
    s32 fsret, fd;

    fd = osBbFOpen(gSaRlFname,"r");
    if(fd<0){
        return SARL_NO_FILE;
    }
    fsret = osBbFStat(fd, &fsStat, NULL, 0);
    PRINTF("%s contains %d bytes\n",gSaRlFname,fsStat.size);
    
    if(fsret !=0)
        return SARL_ERR;
    if(fsStat.size > sizeof gRlBuf)
        return SARL_ERR;

    /* read entire rl file into global buffer */
    if(osBbFRead(fd, 0, gRlBuf, fsStat.size)<0){
        osBbFClose(fd);
        return SARL_ERR;
    }
    
    osBbFClose(fd);
    if((*((u32 *)gRlBuf))>LAUNCH_CRLS)
        return SARL_ERR;
    gNumRls = *(u32 *)gRlBuf;

    return BB_SYSAPP_PASS;
}

int osBbSaRlBundle(BbAppLaunchCrls *rls)
{
    int i, ret;
    BbCrlHead *rl = (BbCrlHead *)(gRlBuf+sizeof(u32));

    memset((void *)rls, 0, sizeof(BbAppLaunchCrls));

    if(gNumRls == 0){
        ret = osBbSaRlInit();
        if(ret == SARL_ERR)
            return ret;
        else if(ret == SARL_NO_FILE){
            PRINTF("Failed to open rl file, proceeding without...\n");
            return BB_SYSAPP_PASS;
        }
        else if(ret != BB_SYSAPP_PASS){
            return SARL_ERR;
        }
    }

    for(i=0;(i<gNumRls)&&(i<LAUNCH_CRLS);i++){

        switch(rl->type){
        case BB_CRL_TYPE_XS:
            if(fillCrlBundle(rl,&rls->tsrl) != BB_SYSAPP_PASS)
               return SARL_ERR;
            break;
        case BB_CRL_TYPE_CP:
            if(fillCrlBundle(rl,&rls->cprl) != BB_SYSAPP_PASS)
               return SARL_ERR;
            break;
        case BB_CRL_TYPE_CA:
            if(fillCrlBundle(rl,&rls->carl) != BB_SYSAPP_PASS)
               return SARL_ERR;
            break;
        default:
            return SARL_ERR;
        }
        rl = (BbCrlHead *)(((u8 *)rl) + sizeof(BbCrlHead) + 
                           sizeof(BbCrlEntry)*rl->numberRevoked);
    }

    return BB_SYSAPP_PASS;
}