2026-08-30 10:53:09 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| 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 <TSN\\Crypto\\ASN1.mqh>
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CNumberDERUtils
|
| | | {
|
| | | public:
|
| | | CNumberDERUtils(void) {}
|
| | | ~CNumberDERUtils(void) {}
|
| | |
|
| | | //---
|
| | | template <typename TNumber>
|
| | | static int DEREstimateLen(const TNumber value, int& k, bool& is_high_encendido, uchar& number_len_size);
|
2026-08-30 15:27:01 -05:00 | | |
|
| | | //---
|
| | | template <typename TNumber>
|
| | | static int DERRead(const uchar& buf[], int r, TNumber& value);
|
2026-08-30 10:53:09 -05:00 | | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| 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 <typename TNumber>
|
| | | 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; \
|
2026-08-30 15:27:01 -05:00 | | | CBL_ASN1_U_WRITELEN(buf, w, lenw, total) \
|
2026-08-30 10:53:09 -05:00 | | | TsnValToBytes<ttype> rp; \
|
| | | rp.value=VALUE; \
|
| | | if(is_high_encendido) \
|
| | | buf[w++] = 0x00; \
|
| | | for(int i = k; i >= 0; i--) \
|
| | | buf[w++] = rp.bytes[i]; \
|
| | | }
|
| | |
|
2026-08-30 15:27:01 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | 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;
|
| | | }
|
2026-08-30 10:53:09 -05:00 | | |
|
| | | //---
|
| | | }
|
| | | #endif // BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH
|