unsigned char * get_astr_userfld(struct asn_bstruct *asnp) { char *func = "get_astr_userfld"; long num; int type, in_seq=0; asnp->abp = chk_asn_buf(asnp, 16); if (ABP == ASN_SEQ) { in_seq = 1; ABP_INC2;} if (ABP != ASN_USERFLD_LABEL) { return asn_error(func, "ASN_USERFLD_LABEL", ASN_USERFLD_LABEL, asnp, 4); } else { ABP_INC2; asnp->abp = get_astr_objid(asnp, &type, NULL, NULL, 0)+2; } if (ABP == ASN_USERFLD_NUM) { asnp->abp +=2; asnp->abp = get_astr_int(asnp, &num)+2; } if (ABP != ASN_USERFLD_DATA) { return asn_error(func, "ASN_USERFLD_DATA", ASN_USERFLD_DATA, asnp, 4); } else { ABP_INC2; asnp->abp = get_astr_userfld_data(asnp)+2; } if (in_seq) ABP_INC2; return asnp->abp; }
unsigned char * get_astr_user(struct asn_bstruct *asnp) { int type; char *func = "get_astr_user"; asnp->abp = chk_asn_buf(asnp,16); ABP_INC2; /* skip SEQ */ if (ABP == ASN_USER_CLASS) { ABP_INC2; asnp->abp = get_astr_str(asnp, NULL, 0) + 2; } if (ABP != ASN_USER_TYPE) { return asn_error(func, "ASN_USER_TYPE", ASN_USER_TYPE, asnp, 4); } else { ABP_INC2; asnp->abp = get_astr_objid(asnp, &type, NULL, NULL, 0) + 2; } if (ABP != ASN_USER_DATA) { return asn_error(func,"ASN_USER_DATA", ASN_USER_DATA, asnp, 4); } else { asnp->abp += 4; /* skip over, data, SEQ */ asnp->abp = chk_asn_buf(asnp,8); asnp->abp = get_astr_userfld(asnp); asnp->abp += 4; } return asnp->abp; }
vector<byte> getNameValue(asnObject *p,string extId) { vector<byte> retVal; for(size_t i=0; i < p->contents.size(); i++ ) { asnObject *n = p->contents[i]; if (n->contents.size()!=1 ) throw asn_error("bad namevalue"); asnObject *nv = n->contents[0]; if (nv->contents.size()!=2 ) throw asn_error("bad namevalue, expecting 2 members"); if (extId == getAlgid( nv->contents[0] )) { retVal.resize(nv->contents[1]->size); copy(nv->contents[1]->body_start,nv->contents[1]->stop,retVal.begin()); } } return retVal; }
unsigned char * get_astr_objid(struct asn_bstruct *asnp, int *type, int *val, char *text, int t_len) { long local_ival; asnp->abp = chk_asn_buf(asnp,16); if (text != NULL) text[0] = '\0'; if (val != NULL) *val = 0; *type = 0; /* object could be text, or could be int */ if (ABP == ASN_OBJ_INT) { ABP_INC2; asnp->abp = get_astr_int(asnp, &local_ival)+2; if (val != NULL) *val = local_ival; *type = 1; } else if (ABP == ASN_OBJ_STR) { ABP_INC2; asnp->abp = get_astr_str(asnp, text, t_len)+2; *type = 2; } else { return asn_error("get_astr_objid","ASN_OBJ_STR",ASN_OBJ_STR,asnp,4); } return asnp->abp; }
unsigned char * get_astr_int(struct asn_bstruct *asnp, long *val) { int v_len, v; v = 0; asnp->abp = chk_asn_buf(asnp,8); if (*asnp->abp++ != ASN_IS_INT) { /* check for int */ return asn_error("get_astr_int", "ASN_IS_INT", ASN_IS_INT, asnp, 4); } else { v_len = *asnp->abp++; while (v_len-- > 0) { v *= 256; v += *asnp->abp++; } } if (v_len == 1 && v > 127) v = 256 - v; else if (v_len == 2 && v > 32767) v = 65526 - v; *val = v; return asnp->abp; }
/* * Write a length field (restricted to values < 2^32-1) and return the * number of bytes this field takes. If ptr is NULL, the length is computed * but nothing is written. If the length would be too large return 0. */ static u_int asn_put_len(u_char *ptr, asn_len_t len) { u_int lenlen, lenlen1; asn_len_t tmp; if (len > ASN_MAXLEN) { asn_error(NULL, "encoding length too long: (%u)", len); return (0); } if (len <= 127) { if (ptr) *ptr++ = (u_char)len; return (1); } else { lenlen = 0; /* compute number of bytes for value (is at least 1) */ for (tmp = len; tmp != 0; tmp >>= 8) lenlen++; if (ptr != NULL) { *ptr++ = (u_char)lenlen | 0x80; lenlen1 = lenlen; while (lenlen1-- > 0) { ptr[lenlen1] = len & 0xff; len >>= 8; } } return (lenlen + 1); }
string getDateStr(asnObject *v) { if (v->size != 13) throw asn_error("invalid date"); string val(10,'.'),a2("20"); copy(a2.begin(),a2.end(), val.begin() + 6 ); copy(v->body_start + 0,v->body_start +2, val.begin() + 8 ); copy(v->body_start + 2,v->body_start +4, val.begin() + 3); copy(v->body_start + 4,v->body_start +6, val.begin() + 0); return val; }
void asnObject::init() { start = begin(); stop = end(); decode(0); if (stop != end() ) { stop++; while (stop != end() && *stop == 0 ) stop++; // maybe we have trailing of zeroes if (stop!=end()) { throw asn_error("extra bytes at the end"); } } }
bool asnCertificate::checkKeyUsage(string id) { asnObject * ext = findExtension(idExtKeyUsage); if (!ext) return false; asnObject decode(ext->body_start,ext->stop,0,bout); if (decode.tag!=SEQUENCE) throw asn_error("invalid ExtKeyUsage"); for(size_t i=0; i < decode.contents.size(); i++) { string comp = getAlgid(decode.contents[i]); if (comp == id ) return true; } return false; }
std::string getAlgid(asnObject *obj) { if (obj->tag != asnObject::OBJECTIDENTIFIER) throw asn_error("expected objectidentifier"); if (obj->size < 3) throw asn_error("invalid OBJID"); byteVec body = byteVec(obj->body_start,obj->stop); unsigned char m1 = (body[0] & 0x28 ) ? 0x28 : (body[0] & 0x50 ? 0x50 : 0); if (!m1) throw asn_error("invalid OBJID byte0"); unsigned char val1 = (m1 >> 5); unsigned char val2 = body[0] & (~m1); std::ostringstream buf; buf << (int)val1 << "." << (int)val2 ; for(size_t i=1;i<body.size();i++) { int val = body[i]; while(body[i] & 0x80 && i < body.size() ) val= ((val & 0x7F) << 7) & (body[i++] & 0x7F); buf << "." << (int)val; } string objStr = buf.str(); return objStr; }
void asnCertificate::init() { if (contents.size() != 3) throw asn_error("Certificate must consist of three elements"); asnObject * tbsCertificate = contents[0]; signatureAlgorithm = contents[1]; signatureValue = contents[2]; if (tbsCertificate->contents.size() < 7) throw asn_error("tbsCertificate must have at least 7 elements"); version = tbsCertificate->contents[0]; serialNumber = tbsCertificate->contents[1]; signatureAlg = tbsCertificate->contents[2]; issuerName = tbsCertificate->contents[3]; validityPeriod = tbsCertificate->contents[4]; if (validityPeriod->contents.size() != 2) throw asn_error("validityPeriod should have 2 members"); subjectName = tbsCertificate->contents[5]; publicKeyInfo = tbsCertificate->contents[6]; if (tbsCertificate->contents.size() >= 8) extensions = tbsCertificate->contents[7]; }
string asnCertificate::getSubject() { string retVal; for(size_t i=0; i < subjectName->contents.size(); i++ ) { asnObject *n = subjectName->contents[i]; if (n->contents.size()!=1 ) throw asn_error("bad namevalue"); asnObject *nv = n->contents[0]; if (nv->contents.size()!=2 ) throw asn_error("bad namevalue, expecting 2 members"); string extId = getAlgid( nv->contents[0] ); int numItems = sizeof(arrNameIds) / sizeof(*arrNameIds); for(int j = 0; j < numItems; j++) { string comp(arrNameIds[j][0]); if (extId == comp) extId = arrNameIds[j][1]; } if (extId!= "CN" && extId != "SN") { //avoid UTF16 for now string val(nv->contents[1]->size ,'0'); copy( nv->contents[1]->body_start,nv->contents[1]->stop,val.begin()); retVal += " ," + extId + " = " + val; } } if (retVal.length() > 2) //remove leading , retVal.erase(0,2); return retVal; }
void asnObject::decode(int tab) { byteIter p = start + 2; if (stop - start < 2) throw asn_error("too few bytes as input"); tag = *start; size = *(start + 1); body_start = start + 2 + ( size & 0x80 ? size & 0x7F : 0 ) ; if (body_start > stop ) throw asn_error("content points too far out"); if(size & 0x80) { if (body_start > start + 6 ) throw asn_error("too many size bytes"); size = 0; while(p < body_start) size= (size << 8) + *p++; } for (int i=tab ; i>0;i--) bout << " "; bout.setf(std::ios::hex, std::ios::basefield); bout << std::setw(2) << std::setfill('0') << (int) tag << " " << std::setw(4) << (int) size;; if (body_start + size > stop) throw asn_error("size is beyond buffer end"); stop = body_start + size; expl_tag = (tag & 0xA0) == 0xA0; if (tag & 0x20) { //constructed, bit6 = 1 tag &= 0x1F; bout << std::endl; tab+=2; while(p < stop) { contents.push_back(new asnObject(p,stop,tab,bout)); p = contents.back()->stop; } tab-=2; if (p != stop) throw asn_error("garbage bytes"); } else { //bit 6= 0 if ( (tag & 0x1F) == 0x1F) throw asn_error("complex tagging"); while(p < stop) bout << " " << std::setw(2) << std::setfill('0') << (int)*p++; bout << std::endl; } }
string asnCertificate::getSubjectAltName() { asnObject * ext = findExtension(idSubjectAltName); if (!ext) return ""; asnObject decode(ext->body_start,ext->stop,0,bout); if (decode.tag!=SEQUENCE) throw asn_error("invalid altName"); std::string ret; for(size_t i=0; i < decode.contents.size(); i++) { ret.resize(ret.size()+ decode.contents[i]->size); copy(decode.contents[i]->body_start,decode.contents[i]->stop, ret.begin()); } return ret; }
unsigned char * get_astr_iseqd(struct asn_bstruct *asnp, unsigned char *query, int nq) { asnp->abp = chk_asn_buf(asnp,2); /* check for the sequence type - NCBIstdaa or NCBIstdeaa */ if (ABP == ASN_SEQINST_NCBIEAA) { ABP_INC2; return get_astr_str(asnp, (char *)query, nq) + 2; } else if (ABP == ASN_SEQINST_NCBISTDAA) { ABP_INC2; return get_astr_octstr(asnp, query, nq) + 2; } else { return asn_error("get_astr_iseqd","",-1,asnp,4); } }
unsigned char * get_astr_seqid (struct asn_bstruct *asnp, long *gi, char *name, char *acc) { int type; int val; *gi = 0; acc[0] = '\0'; while (ABP != '\0') { switch (ABP) { case ASN_BIOSEQ_ID_OBJ: ABP_INC2; asnp->abp = get_astr_objid(asnp, &type, &val, name, MAX_SSTR) + 2; break; case ASN_BIOSEQ_ID_LOCAL: ABP_INC2; asnp->abp = get_astr_str(asnp, name, MAX_SSTR) + 2; break; case ASN_BIOSEQ_ID_GI: ABP_INC2; asnp->abp = get_astr_int(asnp, gi) + 2; break; case ASN_BIOSEQ_ID_GB: case ASN_BIOSEQ_ID_EMBL: case ASN_BIOSEQ_ID_PIR: case ASN_BIOSEQ_ID_SP: case ASN_BIOSEQ_ID_OTHER: ABP_INC2; asnp->abp = get_astr_textid(asnp, name, acc) + 2; break; default: return asn_error("get_atr_seqid", "", -1, asnp,4); } } return asnp->abp; }
/* * Read the next header. This reads the tag (note, that only single * byte tags are supported for now) and the length field. The length field * is restricted to a 32-bit value. * All errors of this function stop the decoding. */ enum asn_err asn_get_header(struct asn_buf *b, u_char *type, asn_len_t *len) { u_int length; if (b->asn_len == 0) { asn_error(b, "no identifier for header"); return (ASN_ERR_EOBUF); } *type = *b->asn_cptr; if ((*type & ASN_TYPE_MASK) > 0x30) { asn_error(b, "types > 0x30 not supported (%u)", *type & ASN_TYPE_MASK); return (ASN_ERR_FAILED); } b->asn_cptr++; b->asn_len--; if (b->asn_len == 0) { asn_error(b, "no length field"); return (ASN_ERR_EOBUF); } if (*b->asn_cptr & 0x80) { length = *b->asn_cptr++ & 0x7f; b->asn_len--; if (length == 0) { asn_error(b, "indefinite length not supported"); return (ASN_ERR_FAILED); } if (length > ASN_MAXLENLEN) { asn_error(b, "long length too long (%u)", length); return (ASN_ERR_FAILED); } if (length > b->asn_len) { asn_error(b, "long length truncated"); return (ASN_ERR_EOBUF); } *len = 0; while (length--) { *len = (*len << 8) | *b->asn_cptr++; b->asn_len--; } } else { *len = *b->asn_cptr++; b->asn_len--; } return (ASN_ERR_OK); }
unsigned char * get_astr_userfld_data(struct asn_bstruct *asnp) { double real; long ival; int bool; ABPP = chk_asn_buf(asnp, 16); switch (ABP) { case ASN_USERFLD_D_STR : ABP_INC2; ABPP = get_astr_str(asnp, NULL, 0) + 2; break; case ASN_USERFLD_D_INT : ABP_INC2; ABPP = get_astr_int(asnp, &ival) + 2; break; case ASN_USERFLD_D_REAL : ABP_INC2; ABPP = get_astr_real(asnp, &real) + 2; break; case ASN_USERFLD_D_BOOL : ABP_INC2; ABPP = get_astr_bool(asnp, &bool) + 2; break; case ASN_USERFLD_D_OS : ABP_INC2; ABPP = get_astr_octstr(asnp, NULL, 0)+2; break; case ASN_USERFLD_D_OSS : asnp->abp += 4; ABPP = get_astr_octstr(asnp, NULL, 0)+4; break; default: return asn_error("get_astr_userfld_data","",0,asnp,4); } return asnp->abp; }
asnObject *asnCertificate::findExtension(std::string ext) { if (!extensions) return 0; if (!extensions->expl_tag || extensions->tag != 3 || extensions->contents.size() != 1 ) throw "invalid extlist"; asnObject *extList = extensions->contents[0]; for (size_t i= 0;i < extList->contents.size();i++) { asnObject *pExt = extList->contents[i]; if (pExt->tag != SEQUENCE || (pExt->contents.size() != 2 && pExt->contents.size() != 3)) throw asn_error("invalid extension"); asnObject *p0 = pExt->contents[0]; string extId = getAlgid(p0); asnObject *value = pExt->contents[1]; if (pExt->contents.size() == 3 ) value = pExt->contents[2]; if (extId == ext) return value; } return 0; }
unsigned char * get_astr_str(struct asn_bstruct *asnp, char *text, int t_len) { int v_len, tv_len; asnp->abp = chk_asn_buf(asnp,2); if (text != NULL) text[0] = '\0'; if (ABP != ASN_IS_STR && ABP != ASN_IS_SSTR) { /* check for str */ return asn_error("get_astr_str", "ASN_IS_STR", ASN_IS_STR, asnp, 4); } asnp->abp++; v_len = *asnp->abp++; if (v_len > 128) { /* need to read the length from the next bytes */ tv_len = v_len &0x7f; asnp->abp = chk_asn_buf(asnp,tv_len); for (v_len =0; tv_len; tv_len--) { v_len = (v_len << 8) + *asnp->abp++; } } /* read v_len bytes */ if (v_len < t_len) { /* the string fits in the buffer */ asnp->abp = read_asn_dest(asnp,v_len, (unsigned char *)text, t_len); } else { /* it does not fit, fill the buffer and skip */ if (t_len > 0) asnp->abp = read_asn_dest(asnp,t_len, (unsigned char *)text, t_len); asnp->abp = read_asn_dest(asnp,v_len - t_len, NULL, 0); } if (text != NULL && t_len > 0) {text[min(v_len,t_len)]='\0';} return asnp->abp; }
unsigned char * get_astr_bioseq(struct asn_bstruct *asnp, long *gi, char *name, char *acc, char *descr, unsigned char **query, int *nq ) { int end_seq = 0; asnp->abp = chk_asn_buf(asnp,32); if (ABP == ASN_SEQ) { end_seq++; ABP_INC2; } if (ABP != ASN_BIOSEQ_ID) { fprintf(stderr, "*** error [%s:%d] - Bioseq - missing ID tag: %2x %2x\n",__FILE__,__LINE__,ABP, asnp->abp[1]); return asnp->abp; } else { /* skip over bioseq-id tag */ ABP_INC2; if (ABP == ASN_SETOF) { /* jump over ASN_SETOF */ ABP_INC2; asnp->abp = get_astr_seqid(asnp, gi, name, acc); ABP_INC2; /* close ASN_SETOF */ } else { return asn_error("get_astr_bioseq","ASN_SEQOF", ASN_SEQOF, asnp, 4); } ABP_INC2; /* jump over seq-id tag end */ } if (ABP == ASN_BIOSEQ_DESCR) { ABP_INC2; asnp->abp = get_astr_seqdescr(asnp, descr); ABP_INC2; /* skip nulls */ } else { descr[0] = '\0';} while (ABP == '\0') { ABP_INC2;} if (ABP != ASN_BIOSEQ_INST) { fprintf(stderr, "*** error [%s:%d] - Bioseq - missing ID tag: %2x %2x\n",__FILE__,__LINE__,ABP, asnp->abp[1]); return asnp->abp; } else { ABP_INC2; asnp->abp = get_astr_seqinst(asnp, query, nq); ABP_INC2; /* skip nulls */ } if (end_seq--) { ABP_INC2; } return asnp->abp; }
int parse_pssm2_asn(struct asn_bstruct *asnp, long *gi, char *name, char *acc, char *descr, unsigned char **query, int *nq, int *n_rows, int *n_cols, double ***freqs, int *pseudo_cnts, char *matrix, double *lambda_p) { int is_protein; int have_rows=0, have_cols=0; long l_val; int have_scores=0; chk_asn_buf(asnp, 32); /* first get the query */ if (memcmp(asnp->abp, "\241\2000\200",4) != 0) { asn_error("parse_pssm2_asn","ASN_PSSM2_QUERY",ASN_PSSM2_QUERY,asnp,4); return -1; } else { asnp->abp+=4; asnp->abp = get_astr_bioseq(asnp, gi, name, acc, descr, query, nq) + 4; } /* finish up the nulls */ /* perhaps we have parsed correctly and do not need this */ /* while (ABP == '\0') { ABP_INC2;} */ if (memcmp(asnp->abp, "\242\2000\200",4) != 0) { asn_error("parse_pssm2_asn","ASN_PSSM2_MATRIX",ASN_PSSM2_MATRIX,asnp,4); return -1; } else { asnp->abp+=4; if (ABP == ASN_PSSM_IS_PROT) { ABP_INC2; asnp->abp = get_astr_bool(asnp, &is_protein)+2; } if (ABP == ASN_PSSM2_MATRIX_NAME) { ABP_INC2; asnp->abp = get_astr_str(asnp, matrix, MAX_SSTR) + 2; } if (ABP == ASN_PSSM2_NCOLS) { ABP_INC2; asnp->abp = get_astr_int(asnp, &l_val)+2; *n_cols = l_val; have_cols = 1; } if (ABP == ASN_PSSM2_NROWS) { ABP_INC2; asnp->abp = get_astr_int(asnp, &l_val)+2; *n_rows = l_val; have_rows = 1; } if (ABP == ASN_PSSM2_SCORES) { /* right now, this is always empty */ ABP_INC2; asnp->abp = get_pssm2_scores(asnp, &have_scores) + 2; if (have_scores) return 0; } if (ABP == ASN_PSSM2_KARLIN_K) { ABP_INC2; asnp->abp = get_astr_packedreal(asnp, &l_val, lambda_p) + 2; } if (ABP == ASN_PSSM2_FREQS) { asnp->abp += 4; asnp->abp = get_pssm2_intermed(asnp, freqs, *n_rows, *n_cols) + 4; } } return 1; }