119 lines
4.4 KiB
MQL5
119 lines
4.4 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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);
|
|
|
|
//---
|
|
template <typename TNumber>
|
|
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 <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; \
|
|
CBL_ASN1_U_WRITELEN(buf, w, lenw, total) \
|
|
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]; \
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
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;
|
|
}
|
|
|
|
//---
|
|
}
|
|
#endif // BIGNUMBERSBYLEO_SRC_UTILS_DER_MQH
|