#include <openssl/x509.h>

static X509_CRL *load_crl(const char * const infile)
    {
    X509_CRL *x=NULL;
    BIO *in=NULL;

    in=BIO_new(BIO_s_file());
    if (in == NULL)
	{
	ERR_print_errors_fp(stderr);
	goto end;
	}

    if (infile == NULL)
	BIO_set_fp(in,stdin,BIO_NOCLOSE);
    else if (BIO_read_filename(in,infile) <= 0)
	{
	perror(infile);
	goto end;
	}
    x=d2i_X509_CRL_bio(in,NULL);
    if (x == NULL)
	{
	fprintf(stderr,"unable to load CRL\n");
	ERR_print_errors_fp(stderr);
	goto end;
	}
	
end:
    BIO_free(in);
    return(x);
    }

static time_t ASN1_GENERALIZEDTIME_get(const ASN1_GENERALIZEDTIME * const s)
	{
	struct tm tm;
	int offset;

	memset(&tm,'\0',sizeof tm);

#define g1(n) ((n)-'0')
#define g2(p) (g1((p)[0])*10+g1((p)[1]))
#define g4(p) g1((p)[0])*1000+g1((p)[1])*100+g2(p+2)

	tm.tm_year=g4(s->data)-1900;
	tm.tm_mon=g2(s->data+4)-1;
	tm.tm_mday=g2(s->data+6);
	tm.tm_hour=g2(s->data+8);
	tm.tm_min=g2(s->data+10);
	tm.tm_sec=g2(s->data+12);
	if(s->data[14] == 'Z')
		offset=0;
	else
		{
		offset=g2(s->data+15)*60+g2(s->data+17);
		if(s->data[14] == '-')
			offset= -offset;
		}
#undef g1
#undef g2
#undef g4

	return timegm(&tm)-offset*60;
	}

static void next_update(const X509_CRL * const crl)
    {
    const ASN1_TIME * const t=X509_CRL_get_nextUpdate(crl);
    const ASN1_GENERALIZEDTIME * const gt=ASN1_TIME_to_generalizedtime(t,NULL);
    const time_t tt=ASN1_GENERALIZEDTIME_get(gt);
    const time_t now=time(NULL);

    printf("%ld\n",tt-now);
    }

int main(int argc,char **argv)
    {
    const char *crlfile;
    const char *function;
    X509_CRL *crl;

    if(argc < 3)
	{
	fprintf(stderr,"%s <crl> [nextupdate]\n",argv[0]);
	exit(1);
	}
    crlfile=argv[1];
    function=argv[2];

    crl=load_crl(crlfile);
    if(!strcmp(function,"nextupdate"))
	next_update(crl);
    else
	{
	fprintf(stderr,"unknown function: %s\n",function);
	exit(2);
	}

    return 0;
    }
