// Find start date of certificate validity period int X509_find_start_date(octet *c,int start) { int j,len; j=start; len=getalen(SEQ,c->val,j); if (len<0) return 0; j+=skip(len); len=getalen(UTC,c->val,j); if (len<0) return 0; j+=skip(len); return j; }
int X509_find_entity_property(octet *c,octet *SOID,int start,int *flen) { int i,j,k,fin,len,tlen; char foid[50]; /*****/ octet FOID= {0,sizeof(foid),foid}; j=start; tlen=getalen(SEQ,c->val,j); if (tlen<0) return 0; j+=skip(tlen); for (k=j; j<k+tlen;) { // search for Owner OID len=getalen(SET,c->val,j); if (len<0) return 0; j+=skip(len); len=getalen(SEQ,c->val,j); if (len<0) return 0; j+=skip(len); len=getalen(OID,c->val,j); if (len<0) return 0; j+=skip(len); fin=j+len; // extract OID FOID.len=len; for (i=0; j<fin; j++) FOID.val[i++]= c->val[j]; len=getalen(ANY,c->val,j); // get text, could be any type if (len<0) return 0; j+=skip(len); if (OCT_comp(&FOID,SOID)) { // if its the right one return *flen=len; return j; } j+=len; // skip over it } *flen=0; /*****/ return 0; }
// Find expiry date of certificate validity period int MCL_X509_find_expiry_date(mcl_octet *c,int start) { int j,len; j=start; len=getalen(SEQ,c->val,j); if (len<0) return 0; j+=skip(len); len=getalen(UTC,c->val,j); if (len<0) return 0; j+=skip(len)+len; len=getalen(UTC,c->val,j); if (len<0) return 0; j+=skip(len); return j; }
// Find index to subject in cert int X509_find_subject(octet *c) { int j,len; j=X509_find_validity(c); len=getalen(SEQ,c->val,j); if (len<0) return 0; j+=skip(len)+len; // skip validity return j; }
// Find index to validity period int X509_find_validity(octet *c) { int j,len; j=X509_find_issuer(c); len=getalen(SEQ,c->val,j); if (len<0) return 0; j+=skip(len)+len; // skip issuer return j; }
// Extract certificate from signed cert int X509_extract_cert(octet *sc,octet *cert) { int i,j,fin,len,k; j=0; len=getalen(SEQ,sc->val,j); if (len<0) return 0; j+=skip(len); k=j; len=getalen(SEQ,sc->val,j); if (len<0) return 0; j+=skip(len); fin=j+len; cert->len=fin-k; for (i=k; i<fin; i++) cert->val[i-k]=sc->val[i]; return 1; }
// Find pointer to main sections of cert, before extracting individual field // Find index to issuer in cert int X509_find_issuer(octet *c) { int j,len; j=0; len=getalen(SEQ,c->val,j); if (len<0) return 0; j+=skip(len); if (len+j!=c->len) return 0; len=getalen(0,c->val,j); if (len<0) return 0; j+=skip(len)+len; //jump over version clause len=getalen(INT,c->val,j); if (len>0) j+=skip(len)+len; // jump over serial number clause (if there is one) len=getalen(SEQ,c->val,j); if (len<0) return 0; j+=skip(len)+len; // jump over signature algorithm return j; }
// Extract Public Key from inside Certificate pktype X509_extract_public_key(octet *c,octet *key) { int i,j,fin,len,sj; char koid[12]; /*****/ octet KOID= {0,sizeof(koid),koid}; pktype ret; ret.type=ret.hash=0; ret.curve=-1; j=0; len=getalen(SEQ,c->val,j); if (len<0) return ret; j+=skip(len); if (len+j!=c->len) return ret; len=getalen(0,c->val,j); if (len<0) return ret; j+=skip(len)+len; //jump over version clause len=getalen(INT,c->val,j); if (len>0) j+=skip(len)+len; // jump over serial number clause (if there is one) len=getalen(SEQ,c->val,j); if (len<0) return ret; j+=skip(len)+len; // jump over signature algorithm len=getalen(SEQ,c->val,j); if (len<0) return ret; j+=skip(len)+len; // skip issuer len=getalen(SEQ,c->val,j); if (len<0) return ret; j+=skip(len)+len; // skip validity len=getalen(SEQ,c->val,j); if (len<0) return ret; j+=skip(len)+len; // skip subject len=getalen(SEQ,c->val,j); if (len<0) return ret; j+=skip(len); // len=getalen(SEQ,c->val,j); if (len<0) return ret; j+=skip(len); // ** Maybe dive in and check Public Key OIDs here? // ecpublicKey & prime256v1, secp384r1 or secp521r1 for ECC // rsapublicKey for RSA sj=j+len; len=getalen(OID,c->val,j); if (len<0) return ret; j+=skip(len); fin=j+len; KOID.len=len; for (i=0; j<fin; j++) KOID.val[i++]= c->val[j]; ret.type=0; if (OCT_comp(&ECPK,&KOID)) ret.type=ECC; if (OCT_comp(&RSAPK,&KOID)) ret.type=RSA; if (ret.type==0) return ret; if (ret.type==ECC) { // which elliptic curve? len=getalen(OID,c->val,j); if (len<0) { ret.type=0; return ret; } j+=skip(len); fin=j+len; KOID.len=len; for (i=0; j<fin; j++) KOID.val[i++]= c->val[j]; if (OCT_comp(&PRIME25519,&KOID)) ret.curve=C25519; /*****/ if (OCT_comp(&PRIME256V1,&KOID)) ret.curve=NIST256; if (OCT_comp(&SECP384R1,&KOID)) ret.curve=NIST384; if (OCT_comp(&SECP521R1,&KOID)) ret.curve=NIST521; } j=sj; // skip to actual Public Key len=getalen(BIT,c->val,j); if (len<0) { ret.type=0; return ret; } j+=skip(len); // j++; len--; // skip bit shift (hopefully 0!) // extract key if (ret.type==ECC) { key->len=len; fin=j+len; for (i=0; j<fin; j++) key->val[i++]= c->val[j]; } if (ret.type==RSA) { // Key is (modulus,exponent) - assume exponent is 65537 len=getalen(SEQ,c->val,j); if (len<0) { ret.type=0; return ret; } j+=skip(len); // len=getalen(INT,c->val,j); // get modulus if (len<0) { ret.type=0; return ret; } j+=skip(len); // if (c->val[j]==0) { j++; len--; // remove leading zero } key->len=len; fin=j+len; for (i=0; j<fin; j++) key->val[i++]= c->val[j]; ret.curve=8*len; } return ret; }
pktype X509_extract_cert_sig(octet *sc,octet *sig) { int i,j,k,fin,len,rlen,sj,ex; char soid[9]; octet SOID= {0,sizeof(soid),soid}; pktype ret; ret.type=0; ret.hash=0; j=0; len=getalen(SEQ,sc->val,j); // Check for expected SEQ clause, and get length if (len<0) return ret; // if not a SEQ clause, there is a problem, exit j+=skip(len); // skip over length to clause contents. Add len to skip clause if (len+j!=sc->len) return ret; len=getalen(SEQ,sc->val,j); if (len<0) return ret; j+=skip(len)+len; // jump over cert to signature OID len=getalen(SEQ,sc->val,j); if (len<0) return ret; j+=skip(len); sj=j+len; // Needed to jump over signature OID // dive in to extract OID len=getalen(OID,sc->val,j); if (len<0) return ret; j+=skip(len); fin=j+len; SOID.len=len; for (i=0; j<fin; j++) SOID.val[i++]= sc->val[j]; // check OID here.. if (OCT_comp(&ECCSHA256,&SOID)) { ret.type=ECC; ret.hash=H256; } if (OCT_comp(&ECCSHA384,&SOID)) { ret.type=ECC; ret.hash=H384; } if (OCT_comp(&ECCSHA512,&SOID)) { ret.type=ECC; ret.hash=H512; } if (OCT_comp(&RSASHA256,&SOID)) { ret.type=RSA; ret.hash=H256; } if (OCT_comp(&RSASHA384,&SOID)) { ret.type=RSA; ret.hash=H384; } if (OCT_comp(&RSASHA512,&SOID)) { ret.type=RSA; ret.hash=H512; } if (ret.type==0) return ret; // unsupported type j=sj; // jump out to signature len=getalen(BIT,sc->val,j); if (len<0) { ret.type=0; return ret; } j+=skip(len); j++; len--; // skip bit shift (hopefully 0!) if (ret.type==ECC) { // signature in the form (r,s) len=getalen(SEQ,sc->val,j); if (len<0) { ret.type=0; return ret; } j+=skip(len); // pick up r part of signature len=getalen(INT,sc->val,j); if (len<0) { ret.type=0; return ret; } j+=skip(len); if (sc->val[j]==0) { // skip leading zero j++; len--; } rlen=bround(len); ex=rlen-len; sig->len=2*rlen; i=0; for (k=0; k<ex; k++) sig->val[i++]=0; fin=j+len; for (; j<fin; j++) sig->val[i++]= sc->val[j]; // pick up s part of signature len=getalen(INT,sc->val,j); if (len<0) { ret.type=0; return ret; } j+=skip(len); if (sc->val[j]==0) { // skip leading zeros j++; len--; } rlen=bround(len); ex=rlen-len; for (k=0; k<ex; k++) sig->val[i++]=0; fin=j+len; for (; j<fin; j++) sig->val[i++]= sc->val[j]; } if (ret.type==RSA) { rlen=bround(len); ex=rlen-len; sig->len=rlen; i=0; for (k=0; k<ex; k++) sig->val[i++]=0; fin=j+len; for (; j<fin; j++) sig->val[i++]= sc->val[j]; } if (ret.hash==H256) ret.curve=NIST256; if (ret.hash==H384) ret.curve=NIST384; if (ret.hash==H512) ret.curve=NIST521; return ret; }