//+------------------------------------------------------------------+ //| DER.mqh | //| Copyright 2026, Niquel Mendoza | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, Niquel Mendoza" #property link "https://www.mql5.com" #property strict #ifndef BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH #define BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ namespace TSN { //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CNumberDERUtils { public: CNumberDERUtils(void) {} ~CNumberDERUtils(void) {} //--- template static int DEREstimateLen(const TNumber value, int& k, bool& is_high_encendido, uchar& number_len_size); //--- template static int DERRead(const uchar& buf[], int r, TNumber& value); }; //+------------------------------------------------------------------+ //| Formado DER esta pensado en si | //| Para usarse con DerEstimateLen, normalemnte en RSA, etc para | //| ASN1 donde se reuqiere (recursion) para el TLV | //+------------------------------------------------------------------+ // TNumber como maximo peude tener para no mparse de 127 // 126 bytes de tamaƱo (mas que sobra para long\ulong y hasta structs..) //+------------------------------------------------------------------+ // devuelve tres cosas // k=desde donde empiza a escibir // is_high_encendido=si el alto esta encneido (para el 0x00) // number_len_size=para ponerlo como valor uchar template static int CNumberDERUtils::DEREstimateLen(const TNumber value, int& k, bool& is_high_encendido, uchar& number_len_size) { const int clz = CBitTricks::CLZ(value); k = (((sizeof(TNumber) << 3) - 1) - clz) >> 3; // posicion del byte mas alto con valor // calculamos directo el high.. en vez de callear una funcion is_high_encendido = (uchar(value >> (k << 3)) & 0x80) != 0; // + 1 para normlzliar number_len_size = uchar(is_high_encendido + k + 1); // // +1 = tag // +1 = lensize (Shoft format) return number_len_size + 1 + 1; } //+------------------------------------------------------------------+ // buf= buffer final // w= indice de escritura // lenw= salida de DERTotalBytes (lenw uchar) // total= salida final total de DERTotalBytes #define NUMBERUTILS_DER_WRITE_NUMBER(buf, w, VALUE, ttype, is_high_encendido, k, lenw, total) \ { \ buf[w++] = CBL_ASN1_TAG_INTEGER; \ CBL_ASN1_U_WRITELEN(buf, w, lenw, total) \ TsnValToBytes rp; \ rp.value=VALUE; \ if(is_high_encendido) \ buf[w++] = 0x00; \ for(int i = k; i >= 0; i--) \ buf[w++] = rp.bytes[i]; \ } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template static int CNumberDERUtils::DERRead(const uchar& buf[], int r, TNumber& value) { //--- if(buf[r++] != CBL_ASN1_TAG_INTEGER) return -1; //--- int t = buf[r++]; if((t & CBL_ASN1_MASK_BYTEALTO) != 0) return -1; // sool short format //--- const int fr = r + t; r = fr - 1; // aqui no chekamso si la info es buena o mala // se supone que ah de coincidor (En caso que no ) // digmoas t=2, buf=3, entonces requiere 4.. por lo qeu se pasa y da fuera de rango // si resulta neceisto se pdora aqui mteer un if if(r >= ArraySize(buf)) // invalido return -1; //--- value = 0; for(int j = 0; j < (t << 3); j += 8) value |= TNumber(buf[r--]) << j; //--- return fr; } //--- } #endif // BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH