CryptoAPI / CNG и ASN.1 - как?
От: morgot  
Дата: 31.05.22 18:37
Оценка:
В Windows есть утилита certutil , которая с флагом -asn имя_файла может распарсить бинарный файл в ASN кодировке. Логично предположить, что существуют какие-то встроенные криптографические апи винды для этого дела.
Подскажите, кто сталкивался, какие.
Знаю про сторонние либы, но тут нужен чистый винапи.
Re: CryptoAPI / CNG и ASN.1 - как?
От: Pzz Россия https://github.com/alexpevzner
Дата: 31.05.22 20:13
Оценка: 1 (1)
Здравствуйте, morgot, Вы писали:

M>Знаю про сторонние либы, но тут нужен чистый винапи.


А точно ли он тебе нужен? С CryptoAPI есть две проблемки:
— он очень мутно документирован, и с ним сложно разобраться
— никто не гарантирует тебе, какие алгоритмы есть на конкретной машине. На твоей может быть какой-то шифр, а на машине заказчика его может и не оказаться.
Re[2]: CryptoAPI / CNG и ASN.1 - как?
От: morgot  
Дата: 01.06.22 10:22
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>А точно ли он тебе нужен?


Да.

Pzz>- он очень мутно документирован, и с ним сложно разобраться


Я это и понял, потому и спрашиваю, мб кто-то разобрался в недрах MSDN.. ну или CNG как вариант, ХР сейчас нет.

Pzz>- никто не гарантирует тебе, какие алгоритмы есть на конкретной машине. На твоей может быть какой-то шифр, а на машине заказчика его может и не оказаться.


думаю, парсер ASN всяко есть, это же не шифрование.
Re[3]: CryptoAPI / CNG и ASN.1 - как?
От: kov_serg Россия  
Дата: 01.06.22 11:16
Оценка: +1
Здравствуйте, morgot, Вы писали:

M>думаю, парсер ASN всяко есть, это же не шифрование.

ans1 очень простой формат, но как и что туда укладывают бывает очень не однозначным.
я такой парсер сгородил.
  вспомогательный конструкции
// packet ----------------------------------------------------------------------
typedef struct {
  unsigned char* data;
  int size,limit,pos,ovf;
} packet_t;
void pkt_init(packet_t *p,unsigned char* buf,int buf_size) {
  p->data=buf;
  p->size=0;
  p->limit=buf_size;
  p->pos=0;
  p->ovf=0;
}
void pkt_clone(packet_t* dst,packet_t *src) {
  *dst=*src;
}
int pkt_end(packet_t *p) { return p->pos>=p->size; }
int pkt_left(packet_t *p) { return p->size-p->pos; }
int pkt_get(packet_t *p) { return p->pos<p->size ? p->data[p->pos++] : 0; }
int pkt_put(packet_t *p,int v) {
  if (p->pos>=p->size) {
    if (p->size>=p->limit) return p->ovf=1;
    p->size++;
  }
  if (p->pos>=p->size) p->ovf=1; else p->data[p->pos++]=v;
  return p->ovf;
}
int pkt_skip(packet_t *p,int size) {
  if (size>0) {
    p->pos+=size;
    if (p->pos>p->size) { p->ovf=1; p->pos=p->size; }
  }
  return p->ovf;
}
void pkt_sub(packet_t* dst,packet_t *src,int size) {
  *dst=*src;
  dst->size=src->pos+size;
  if (dst->size>src->size) { dst->size=src->size; dst->ovf=1; }
}
int pkt_gets(packet_t* p,unsigned char* data,int size) {
  int i;
  for(i=0;i<size;++i) data[i]=pkt_get(p);
  return p->ovf;
}
int pkt_readfile(packet_t* p,const char* name) {
  FILE *f;
  f=fopen(name,"rb"); if (!f) return 2;
  fseek(f,0,SEEK_END);
  if (ftell(f)>p->limit) p->ovf=1; 
  fseek(f,0,SEEK_SET);
  p->size=fread(p->data,1,p->limit,f);
  p->pos=0;
  fclose(f);
  return p->ovf;
}
// asn1 ------------------------------------------------------------------------
int asn1_len(packet_t *p) {
  int x,r;
  x=pkt_get(p);
  if (x<128) return x;
  x&=127;
  for(r=0;x>0;--x) {
    r<<=8;
    r|=pkt_get(p);
  }
  return r;
}
int asn1_num(packet_t *p) {
  int x,r=0;
  do { 
    x=pkt_get(p);
    r=(r<<7)|(x&127);
  } while(x&128);
  return r;
}
// asn1 parser -----------------------------------------------------------------
typedef struct {
  int level,index;
  int tag,tag_composite,tag_pos,tag_class,tag_type,tag_len;
  packet_t body[1];
  struct asn1_parser_tag_t *parent;
} asn1_parser_tag_t;

typedef struct {
  void *tag_ctx;
  int (*tag)(void* ctx,asn1_parser_tag_t* tag);
} asn1_parser_cfg_t;

typedef struct {
  packet_t *packet;
  asn1_parser_cfg_t *cfg;
} asn1_parser_t;

Это весь парсер
static int asn1_parse_tag(packet_t *p,
  asn1_parser_cfg_t *cfg,
  asn1_parser_tag_t *parent,
  int stream)
{
  enum {
    ASN1_MASK_MULTI=0x20, ASN1_MASK_TYPE=0x1F,
    ASN1_MASK_CLASS=0xC0, ASN1_SHIFT_CLASS=6
  };
  asn1_parser_tag_t tag[1];packet_t ps[1];int rc;

  tag->index=0;
  tag->level=parent ? parent->level+1 : 0;
  while(!pkt_end(p)) {
    if (stream) {
      if (p->pos+1<p->size && p->data[p->pos]==0 && p->data[p->pos+1]==0) {
        p->pos+=2; break;
      }
    }
    tag->tag_pos=p->pos;
    tag->tag=pkt_get(p);
    tag->tag_type=tag->tag&ASN1_MASK_TYPE;
    if (tag->tag_type==ASN1_MASK_TYPE) tag->tag_type=asn1_num(p);
    tag->tag_class=(tag->tag&ASN1_MASK_CLASS)>>ASN1_SHIFT_CLASS;
    tag->tag_composite=tag->tag&ASN1_MASK_MULTI;
    tag->tag_len=asn1_len(p);
    if (tag->tag_len==0) { // stream
      pkt_sub(ps,p,pkt_left(p));
      if (tag->tag_composite) rc=asn1_parse_tag(ps,cfg,tag,1); else {
        for(rc=2;ps->pos<ps->size;) {
          while(ps->pos<ps->size && ps->data[ps->pos]!=0) ps->pos++;
          if (ps->pos+1<ps->size && ps->data[++ps->pos]==0) {
            ps->pos++; rc=0; break;
          }
        }
      }
      if (rc) return rc;
      tag->tag_len=ps->pos-p->pos-2;
      pkt_sub(tag->body,p,tag->tag_len);
      rc=cfg->tag(cfg->tag_ctx,tag); if (rc) return rc;
      p->pos=ps->pos;
    } else {
      pkt_sub(tag->body,p,tag->tag_len);
      rc=cfg->tag(cfg->tag_ctx,tag); if (rc) return rc;
      if (tag->tag_composite) {
        pkt_sub(tag->body,p,tag->tag_len);
        rc=asn1_parse_tag(tag->body,cfg,tag,0); if (rc) return rc;
      }
      pkt_skip(p,tag->tag_len);
    }
    tag->index++;
    if (tag->level==0) break; // only one root element
  }
  return 0;
}
int asn1_parse(packet_t *p,asn1_parser_cfg_t *cfg) { 
  return asn1_parse_tag(p,cfg,0,0);
}

Потом просто задаёшь селектор в cfg->tag и вынимаешь нужные поля.
Re[3]: CryptoAPI / CNG и ASN.1 - как?
От: Pzz Россия https://github.com/alexpevzner
Дата: 01.06.22 22:57
Оценка:
Здравствуйте, morgot, Вы писали:

Pzz>>А точно ли он тебе нужен?


M>Да.


А можешь рассказать, зачем?

Pzz>>- никто не гарантирует тебе, какие алгоритмы есть на конкретной машине. На твоей может быть какой-то шифр, а на машине заказчика его может и не оказаться.


M>думаю, парсер ASN всяко есть, это же не шифрование.


Ой, не факт. С него станется не понимать, например, указанные в сертификате алгоритмы, если они не поддерживаются на данной венде. Или перестать понимать их после очередного апгрейда.
Re[4]: CryptoAPI / CNG и ASN.1 - как?
От: morgot  
Дата: 03.06.22 12:53
Оценка: 1 (1)
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, morgot, Вы писали:


Pzz>>>А точно ли он тебе нужен?


M>>Да.


Pzz>А можешь рассказать, зачем?


Не люблю лишние зависимости неясно от кого. Стараюсь максимально обходиться одним WinApi (NativeApi).
Конечно, это холиварный вопрос, но я не понимаю, зачем брать допустим что-то для http, при наличии вининет.
Re[5]: CryptoAPI / CNG и ASN.1 - как?
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.06.22 13:20
Оценка:
Здравствуйте, morgot, Вы писали:

Pzz>>А можешь рассказать, зачем?


M>Не люблю лишние зависимости неясно от кого. Стараюсь максимально обходиться одним WinApi (NativeApi).


Потому, что если ты используешь какой-нибудь условный OpenSSL или GNU TLS, то ты всегда точно знаешь, чем ты располагаешь. А с CryptoAPI у тебя набор возможностей сильно зависит от установленных криптопровайдеров, а это вообще не в твоих руках, и может зависеть от версии операционной системы. И после очередного апдейта системы набор возможностей может измениться. Из-за экспортных ограничений, например, которые не являются константой, или из-за какого-то внутреннего решения Microsoft.

В общем, ищешь ты себе приключений на собственную голову. Причем приключения будут такого рода, что у тебя все работает, еще у 1000 человек, с которыми ты как-то общаешься, тоже все работает. А у нового клиента, который находится в максимально неудобном для тебя часовом поясе, не умеет описывать свои проблемы и присылать логи, по телефону тоже ему не дозвонишься, а только бумажная почта на собаках через тундру, вообще ничего не работает, и он не может тебе толком объяснить, в чем дело, но очень недоволен и шлет всяческие проклятия.

По-моему, единственная причина использовать CryptoAPI — это необходимость официальной сертификации твоего изделия. Тут, при использовании сторонних библиотек, могут возникнуть проблемы.

M>Конечно, это холиварный вопрос, но я не понимаю, зачем брать допустим что-то для http, при наличии вининет.


Если тебе надо страничку с сайта скачать, то незачем. Если тебе надо общаться по HTTP, допустим, с принтером, то рано или поздно тебе захочется получить очень детальный доступ к тому, как, к примеру, заполняются всякие разные поля в HTTP-заголовке (а иногда и такое туда написать, что противоречит RFC, а, значит, вининет тебе этого не даст сделать, но без этого твой принтер просто не работает, хотя и должен).
Re[4]: CryptoAPI / CNG и ASN.1 - как?
От: morgot  
Дата: 03.06.22 14:26
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>я такой парсер сгородил.


А как его использовать? Вот допустим у меня есть файл или массив с asn данными. как парсить?
Re[5]: CryptoAPI / CNG и ASN.1 - как?
От: kov_serg Россия  
Дата: 03.06.22 19:03
Оценка: +1
Здравствуйте, morgot, Вы писали:

M>А как его использовать? Вот допустим у меня есть файл или массив с asn данными. как парсить?

  вспомогательные функции
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// packet ----------------------------------------------------------------------
typedef struct {
  unsigned char* data;
  int size,limit,pos,ovf;
} packet_t;
void pkt_init(packet_t *p,unsigned char* buf,int buf_size) {
  p->data=buf;
  p->size=0;
  p->limit=buf_size;
  p->pos=0;
  p->ovf=0;
}
void pkt_clone(packet_t* dst,packet_t *src) {
  *dst=*src;
}
int pkt_end(packet_t *p) { return p->pos>=p->size; }
int pkt_left(packet_t *p) { return p->size-p->pos; }
int pkt_get(packet_t *p) { return p->pos<p->size ? p->data[p->pos++] : 0; }
int pkt_put(packet_t *p,int v) {
  if (p->pos>=p->size) {
    if (p->size>=p->limit) return p->ovf=1;
    p->size++;
  }
  if (p->pos>=p->size) p->ovf=1; else p->data[p->pos++]=v;
  return p->ovf;
}
int pkt_skip(packet_t *p,int size) {
  if (size>0) {
    p->pos+=size;
    if (p->pos>p->size) { p->ovf=1; p->pos=p->size; }
  }
  return p->ovf;
}
void pkt_sub(packet_t* dst,packet_t *src,int size) {
  *dst=*src;
  dst->size=src->pos+size;
  if (dst->size>src->size) { dst->size=src->size; dst->ovf=1; }
}
int pkt_gets(packet_t* p,unsigned char* data,int size) {
  int i;
  for(i=0;i<size;++i) data[i]=pkt_get(p);
  return p->ovf;
}
int pkt_readfile(packet_t* p,const char* name) {
  FILE *f;
  f=fopen(name,"rb"); if (!f) return 2;
  fseek(f,0,SEEK_END);
  if (ftell(f)>p->limit) p->ovf=1; 
  fseek(f,0,SEEK_SET);
  p->size=fread(p->data,1,p->limit,f);
  p->pos=0;
  fclose(f);
  return p->ovf;
}
// asn1 ------------------------------------------------------------------------
int asn1_len(packet_t *p) {
  int x,r;
  x=pkt_get(p);
  if (x<128) return x;
  x&=127;
  for(r=0;x>0;--x) {
    r<<=8;
    r|=pkt_get(p);
  }
  return r;
}
int asn1_num(packet_t *p) {
  int x,r=0;
  do { 
    x=pkt_get(p);
    r=(r<<7)|(x&127);
  } while(x&128);
  return r;
}
// asn1 parser -----------------------------------------------------------------
typedef struct {
  int level,index;
  int tag,tag_composite,tag_pos,tag_class,tag_type,tag_len;
  packet_t body[1];
  struct asn1_parser_tag_t *parent;
} asn1_parser_tag_t;

typedef struct {
  void *tag_ctx;
  int (*tag)(void* ctx,asn1_parser_tag_t* tag);
} asn1_parser_cfg_t;

typedef struct {
  packet_t *packet;
  asn1_parser_cfg_t *cfg;
} asn1_parser_t;
static int asn1_parse_tag(packet_t *p,
  asn1_parser_cfg_t *cfg,
  asn1_parser_tag_t *parent,
  int stream)
{
  enum {
    ASN1_MASK_MULTI=0x20, ASN1_MASK_TYPE=0x1F,
    ASN1_MASK_CLASS=0xC0, ASN1_SHIFT_CLASS=6
  };
  enum { TAG_NULL=5 };
  asn1_parser_tag_t tag[1];packet_t ps[1];int rc;

  tag->index=0;
  tag->level=parent ? parent->level+1 : 0;
  while(!pkt_end(p)) {
    if (stream) {
      if (p->pos+1<p->size && p->data[p->pos]==0 && p->data[p->pos+1]==0) {
        p->pos+=2; break;
      }
    }
    tag->tag_pos=p->pos;
    tag->tag=pkt_get(p);
    tag->tag_type=tag->tag&ASN1_MASK_TYPE;
    if (tag->tag_type==ASN1_MASK_TYPE) tag->tag_type=asn1_num(p);
    tag->tag_class=(tag->tag&ASN1_MASK_CLASS)>>ASN1_SHIFT_CLASS;
    tag->tag_composite=tag->tag&ASN1_MASK_MULTI;
    tag->tag_len=asn1_len(p);
    if (tag->tag_len==0 && (tag->tag_type!=TAG_NULL || tag->tag_class!=0)) {
      pkt_sub(ps,p,pkt_left(p)); // stream
      if (tag->tag_composite) rc=asn1_parse_tag(ps,cfg,tag,1); else {
        for(rc=2;ps->pos<ps->size;) {
          while(ps->pos<ps->size && ps->data[ps->pos]!=0) ps->pos++;
          if (ps->pos+1<ps->size && ps->data[++ps->pos]==0) {
            ps->pos++; rc=0; break;
          }
        }
      }
      if (rc) return rc;
      tag->tag_len=ps->pos-p->pos-2;
      pkt_sub(tag->body,p,tag->tag_len);
      rc=cfg->tag(cfg->tag_ctx,tag); if (rc) return rc;
      p->pos=ps->pos;
    } else {
      pkt_sub(tag->body,p,tag->tag_len);
      rc=cfg->tag(cfg->tag_ctx,tag); if (rc) return rc;
      if (tag->tag_composite) {
        pkt_sub(tag->body,p,tag->tag_len);
        rc=asn1_parse_tag(tag->body,cfg,tag,0); if (rc) return rc;
      }
      pkt_skip(p,tag->tag_len);
    }
    tag->index++;
    if (tag->level==0) break; // only one root element
  }
  return 0;
}
int asn1_parse(packet_t *p,asn1_parser_cfg_t *cfg) { 
  return asn1_parse_tag(p,cfg,0,0);
}
//-- base64 --------------------------------------------------------------------
static int from_base64(char c) {
  if (c>='A' && c<='Z') return c-'A';
  if (c>='a' && c<='z') return c-'a'+26;
  if (c>='0' && c<='9') return c-'0'+52;
  if (c=='+') return 62;
  if (c=='/') return 63;
  return -1;
}
int pkt_base64_decode(packet_t *pkt,const char* text) {
  int acc=0, l1=0, l2=0, rc=0;
  const char* p=text;
  while(*p) {
    char c=*p++;
    int v=from_base64(c);
    if (v<0) { if (c=='=') l2+=6; continue; }
    acc=(acc<<6)|v; l1+=6; l2=0;
    if (l1>=24) {
      pkt_put(pkt,acc>>16);
      pkt_put(pkt,acc>>8);
      pkt_put(pkt,acc);
      l1=0;
    }
  }
  if (l1>0) {
    if (l1+l2!=24) rc=1;
    if (l2>12) { l2=12; rc=2; }
    acc<<=l2;  pkt_put(pkt,acc>>16);
    if (l2<12) pkt_put(pkt,acc>>8);
    if (l2<6)  pkt_put(pkt,acc);
  }
  return rc;
}
//-- hex_dump ------------------------------------------------------------------
static void hex_dump(packet_t *pkt,int level) {
  int w=16,i,a=0;
  while(a<pkt->size) {
    for(i=0;i<level;i++) printf("  ");
    printf("%04X ",a);
    for(i=0;i<w;i++) {
      if (i+a<pkt->size) printf(" %02X",pkt->data[a+i]&255); else printf(" --");
    }
    printf("  |");
    for(i=0;i<w;i++) {
      char c='.'; if (i+a<pkt->size) c=pkt->data[a+i];
      if (c<32 || c>=127) c='.';
      printf("%c",c);
    }    
    printf("|\n");
    a+=w;
  }
}
//-- utils ---------------------------------------------------------------------
static int wr_num(packet_t *res,unsigned n) {
  if (n>=10) wr_num(res,n/10);
  return pkt_put(res,'0'+n%10);
}
static int wr_oid(packet_t *res,packet_t* p) {
  int x;
  if (pkt_end(p)) return 1;
  x=pkt_get(p);
  wr_num(res,x/40);
  pkt_put(res,'.');
  wr_num(res,x%40);
  while(!pkt_end(p)) {
    x=asn1_num(p);
    pkt_put(res,'.');
    wr_num(res,x);
  }
  return res->ovf;
}
static int sprint_oid(char* buf,int buf_size,packet_t *oid) {
  packet_t clone[1],text[1];
  pkt_init(text,buf,buf_size);
  pkt_clone(clone,oid);
  wr_oid(text,clone);
  return pkt_put(text,0);
}
enum {
  TAG_CLASS_UNIVERSAL=0,
  TAG_CLASS_APPLICATION=1,
  TAG_CLASS_CONTEXT_SPECIFIC=2,
  TAG_CLASS_PRIVATE=3
};
static const char* get_classname(int c) {
  switch(c) {
    case 0: return "Universal";
    case 1: return "Application";
    case 2: return "Context-specific";
    case 3: return "Private";
  }
  return "";
}
enum {
  TAG_TYPE_BOOLEAN=1,
  TAG_TYPE_INTEGER=2,
  TAG_TYPE_BIT_STRING=3,
  TAG_TYPE_OCTET_STRING=4,
  TAG_TYPE_NULL=5,
  TAG_TYPE_OID=6,
  TAG_TYPE_OBJECT_DESCRIPTOR=7,
  TAG_TYPE_INSTANCE_OF=8,
  TAG_TYPE_REAL=9,
  TAG_TYPE_ENUMERATED=10,
  TAG_TYPE_EMBEDDED=11,
  TAG_TYPE_UTF8STRING=12,
  TAG_TYPE_RELATIVE_OID=13,
  TAG_TYPE_SEQUENCE=16,
  TAG_TYPE_SET=17,
  TAG_TYPE_NUMERIC_STRING=18,
  TAG_TYPE_PRINTABLE_STRING=19,
  TAG_TYPE_TELETEXT_STRING=20,
  TAG_TYPE_VIDEOTEXT_STRING=21,
  TAG_TYPE_IA5STRING=22,
  TAG_TYPE_UTCTIME=23,
  TAG_TYPE_GENERALIZEDTIME=24,
  TAG_TYPE_GRAPHICS_STRING=25,
  TAG_TYPE_VISIBLE_STRING=26,
  TAG_TYPE_GENERAL_STRING=27,
  TAG_TYPE_UNIVERSAL_STRING=28,
  TAG_TYPE_CHARACTER_STRING=29,
  TAG_TYPE_BMP_STRING=30
};
static const char* get_typename(int type) {
  switch(type) {
    case  0: return "reserved"; // for BER
    case  1: return "BOOLEAN";
    case  2: return "INTEGER";
    case  3: return "BIT_STRING";
    case  4: return "OCTET_STRING";
    case  5: return "NULL";
    case  6: return "OID";
    case  7: return "ObjectDescriptor";
    case  8: return "INSTANCE_OF";// EXTERNAL
    case  9: return "REAL";
    case 10: return "ENUMERATED";
    case 11: return "EMBEDDED_PDV";
    case 12: return "UTF8String";
    case 13: return "RELATIVE-OID";
    case 16: return "SEQUENCE";
    case 17: return "SET";
    case 18: return "NumericString";
    case 19: return "PrintableString";
    case 20: return "TeletexString"; // T61String
    case 21: return "VideotexString";
    case 22: return "IA5String";
    case 23: return "UTCTime";
    case 24: return "GeneralizedTime";
    case 25: return "GraphicString";
    case 26: return "VisibleString";// ISO646String
    case 27: return "GeneralString";
    case 28: return "UniversalString";
    case 29: return "CHARACTER_STRING";
    case 30: return "BMPString";
  }
  return "unknown";
}
static const char* get_oid_desc(const char* oid) {
  if (strcmp(oid,"1.2.840.113549.1.1.1")==0) return "rsaEncryption";
  if (strcmp(oid,"1.2.840.113549.1.1.11")==0) return "sha256WithRSAEncryption";
  if (strcmp(oid,"1.3.6.1.4.1.11129.2.4.2")==0) return "Google.Extended validation certificates";
  if (strcmp(oid,"1.3.6.1.5.5.7.1.1")==0) return "Certificate Authority Information Access";
  if (strcmp(oid,"2.5.29.14")==0) return "Subject key identifier";
  if (strcmp(oid,"2.5.29.15")==0) return "Key usage";
  if (strcmp(oid,"2.5.29.17")==0) return "Subject alternative name";
  if (strcmp(oid,"2.5.29.19")==0) return "Basic constraints";
  if (strcmp(oid,"2.5.29.31")==0) return "Certificate Revocation List distribution points";
  if (strcmp(oid,"2.5.29.32")==0) return "Certificate policies";
  if (strcmp(oid,"2.5.29.35")==0) return "Authority key identifier";
  if (strcmp(oid,"2.5.29.37")==0) return "Certificate extension: extKeyUsage (Extended key usage)";
  if (strcmp(oid,"2.5.4.10")==0) return "Organization name";
  if (strcmp(oid,"2.5.4.3")==0) return "Common name";
  if (strcmp(oid,"2.5.4.6")==0) return "Country name";
  return "?"; // https://oidref.com/
}

//------------------------------------------------------------------------------

static const char *rsdn_pem=
  "MIIGmTCCBYGgAwIBAgIQBszIGrUjrdfJZsel39d9bDANBgkqhkiG9w0BAQsFADBZ"
  "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTMwMQYDVQQDEypH"
  "ZW9UcnVzdCBUTFMgRFYgUlNBIE1peGVkIFNIQTI1NiAyMDIwIENBLTEwHhcNMjIw"
  "MTEwMDAwMDAwWhcNMjMwMjEwMjM1OTU5WjAUMRIwEAYDVQQDDAkqLnJzZG4ucnUw"
  "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTyKAV5iRFGMjIJg8Hf4fP"
  "nLMocb3jkNLcCiS4Q0KMs9oP94uMdWk7TdYeN4QHDM2Z3ZniazYA7hV2uucf6MnF"
  "YHQiRnjBAFdiEMW+N5srd+VnVQd+gj2PazIO1k27Qk1yOu64WwVY7oyf+TwyinLM"
  "pJqR6d2puQGAmAIqEtQqqylCPUNHaoG9WNY6XT6P8kIzTSAztcgEoBbw5RUpGoUN"
  "D6sBMBTvkhlUFrTxP58Fs2P4MOpQvj9pHeoShn7UHbm8yyVhtxoExBq/V4T19yOy"
  "gyVJacOLnHhMz0EnNcmTcRCyghnH/r6MnUeCIg/TbzSvUH1eo9ao8TxoAQBPp1c7"
  "AgMBAAGjggOgMIIDnDAfBgNVHSMEGDAWgBQSyYibL8lEen0S8d9AA0KYksck1jAd"
  "BgNVHQ4EFgQUMyHFa1I+XDBMh5komaLp8sw1JvgwMwYDVR0RBCwwKoIJKi5yc2Ru"
  "LnJ1ggoqLnJzZG4ub3Jnggdyc2RuLnJ1gghyc2RuLm9yZzAOBgNVHQ8BAf8EBAMC"
  "BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMIGfBgNVHR8EgZcwgZQw"
  "SKBGoESGQmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9HZW9UcnVzdFRMU0RWUlNB"
  "TWl4ZWRTSEEyNTYyMDIwQ0EtMS0xLmNybDBIoEagRIZCaHR0cDovL2NybDQuZGln"
  "aWNlcnQuY29tL0dlb1RydXN0VExTRFZSU0FNaXhlZFNIQTI1NjIwMjBDQS0xLTEu"
  "Y3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQIBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93"
  "d3cuZGlnaWNlcnQuY29tL0NQUzCBhQYIKwYBBQUHAQEEeTB3MCQGCCsGAQUFBzAB"
  "hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTwYIKwYBBQUHMAKGQ2h0dHA6Ly9j"
  "YWNlcnRzLmRpZ2ljZXJ0LmNvbS9HZW9UcnVzdFRMU0RWUlNBTWl4ZWRTSEEyNTYy"
  "MDIwQ0EtMS5jcnQwCQYDVR0TBAIwADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFp"
  "AHYArfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgooAAAF+QyqgywAABAMA"
  "RzBFAiEApies/du+wITdxwxwtcHEYiLgW0ZMe1q3Vf9nsePArOUCIE/3GJFYoCRw"
  "a10NhqTSNa45/ClhcQHweu55wLfyLIouAHYANc8ZG7+xbFe/D61MbULLu7YnICZR"
  "6j/hKu+oA8M71kwAAAF+QyqgvAAABAMARzBFAiAkR4+rsxVJTuRxDiA5qhO40JVj"
  "aTZqzslwaQ+GT4jONgIhAI9grI0nmKt1LLvwaHqEIC4gvUlkW50RHW817jQYQOYp"
  "AHcAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAF+Qyqg8gAABAMA"
  "SDBGAiEAy6boPn7iOVr2TPYKRRBA2/Ab/lTLFWxNRHjhYmImZA4CIQDYoM0Iiqfi"
  "H1YI1IIql8+2XPxjIx5tUZHgUHpVfddSbTANBgkqhkiG9w0BAQsFAAOCAQEANrof"
  "Ly0bSOS4XeUCrNNlHTnK+RnlRrLEHyGn7gGk4e+vyn9AcTzcEH7xJP3JFvTsDZAt"
  "g4dL8eoGZOrLHW9fumV16mqHqksMCuZAo0P5Cgj9UOeppvAcnlqsMqF7BNK2AC6f"
  "M08tEeJKxK375ZQut2Ge//cn/CvBt4X3VdvIkXyKh41c/AULtgiJW8aEOtUIwuf3"
  "E8ICFa5OkfD3AO7QIIjn2CbFAeh72jqtzHM95wamYsjiiHnVNrtZAAWEoywyV4iK"
  "eDmzT3/GXf6rVny0zoe6wWI5otHwLV/u5ATvWLVSDGUtqjh6GSgDOG4/Td0xLenK"
  "DIyc4DmeunrJZX6yzw==";
Примерно так:
static int dump_tag(void* ctx,asn1_parser_tag_t* tag) {
  int i; packet_t pkt[1];
  pkt->data=tag->body->data+tag->body->pos;
  pkt->size=tag->body->size-tag->body->pos;
  pkt->pos=0;pkt->ovf=0;pkt->limit=0;
  
  for(i=0;i<tag->level;i++) printf("  ");
  if (tag->tag_class==TAG_CLASS_UNIVERSAL && tag->tag_type==TAG_TYPE_OID) {
      enum { buf_size=80 }; char buf[buf_size+1]; buf[buf_size]=0;
      sprint_oid(buf,buf_size,pkt);
      printf("%d. OID=%s (%s)\n",tag->index,buf,get_oid_desc(buf));
  } else {
    printf("%d. %s(%d)%s ofs=0x%X size=%d\n",
      tag->index,
      tag->tag_class==TAG_CLASS_UNIVERSAL?
        get_typename(tag->tag_type):get_classname(tag->tag_class),
      tag->tag_type,
      tag->tag_composite?" composite":"",
      tag->tag_pos, tag->tag_len
      );
  }
  if (!tag->tag_composite) hex_dump(pkt,tag->level+1);
  return 0;
}

int main(int argc, char const *argv[]) {
  enum { buf_limit=4096 }; char buf[buf_limit];
  packet_t pkt[1]; asn1_parser_cfg_t cfg[1]; int rc;

  pkt_init(pkt,buf,buf_limit);
  rc=pkt_base64_decode(pkt,rsdn_pem);
  if (pkt->ovf) rc=3; if (rc) { printf("error=%d\n",rc); return rc; }
  
  pkt->pos=0;
  cfg->tag_ctx=0;
  cfg->tag=dump_tag;
  asn1_parse(pkt,cfg);
  return 0;
}
  выхлоп
0. SEQUENCE(16) composite ofs=0x0 size=1689
  0. SEQUENCE(16) composite ofs=0x4 size=1409
    0. Context-specific(0) composite ofs=0x8 size=3
      0. INTEGER(2) ofs=0xA size=1
        0000  02 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  |................|
    1. INTEGER(2) ofs=0xD size=16
      0000  06 CC C8 1A B5 23 AD D7 C9 66 C7 A5 DF D7 7D 6C  |.....#...f....}l|
    2. SEQUENCE(16) composite ofs=0x1F size=13
      0. OID=1.2.840.113549.1.1.11 (sha256WithRSAEncryption)
        0000  2A 86 48 86 F7 0D 01 01 0B -- -- -- -- -- -- --  |*.H.............|
      1. NULL(5) ofs=0x2C size=0
    3. SEQUENCE(16) composite ofs=0x2E size=89
      0. SET(17) composite ofs=0x30 size=11
        0. SEQUENCE(16) composite ofs=0x32 size=9
          0. OID=2.5.4.6 (Country name)
            0000  55 04 06 -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. PrintableString(19) ofs=0x39 size=2
            0000  55 53 -- -- -- -- -- -- -- -- -- -- -- -- -- --  |US..............|
      1. SET(17) composite ofs=0x3D size=21
        0. SEQUENCE(16) composite ofs=0x3F size=19
          0. OID=2.5.4.10 (Organization name)
            0000  55 04 0A -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. PrintableString(19) ofs=0x46 size=12
            0000  44 69 67 69 43 65 72 74 20 49 6E 63 -- -- -- --  |DigiCert Inc....|
      2. SET(17) composite ofs=0x54 size=51
        0. SEQUENCE(16) composite ofs=0x56 size=49
          0. OID=2.5.4.3 (Common name)
            0000  55 04 03 -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. PrintableString(19) ofs=0x5D size=42
            0000  47 65 6F 54 72 75 73 74 20 54 4C 53 20 44 56 20  |GeoTrust TLS DV |
            0010  52 53 41 20 4D 69 78 65 64 20 53 48 41 32 35 36  |RSA Mixed SHA256|
            0020  20 32 30 32 30 20 43 41 2D 31 -- -- -- -- -- --  | 2020 CA-1......|
    4. SEQUENCE(16) composite ofs=0x89 size=30
      0. UTCTime(23) ofs=0x8B size=13
        0000  32 32 30 31 31 30 30 30 30 30 30 30 5A -- -- --  |220110000000Z...|
      1. UTCTime(23) ofs=0x9A size=13
        0000  32 33 30 32 31 30 32 33 35 39 35 39 5A -- -- --  |230210235959Z...|
    5. SEQUENCE(16) composite ofs=0xA9 size=20
      0. SET(17) composite ofs=0xAB size=18
        0. SEQUENCE(16) composite ofs=0xAD size=16
          0. OID=2.5.4.3 (Common name)
            0000  55 04 03 -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. UTF8String(12) ofs=0xB4 size=9
            0000  2A 2E 72 73 64 6E 2E 72 75 -- -- -- -- -- -- --  |*.rsdn.ru.......|
    6. SEQUENCE(16) composite ofs=0xBF size=290
      0. SEQUENCE(16) composite ofs=0xC3 size=13
        0. OID=1.2.840.113549.1.1.1 (rsaEncryption)
          0000  2A 86 48 86 F7 0D 01 01 01 -- -- -- -- -- -- --  |*.H.............|
        1. NULL(5) ofs=0xD0 size=0
      1. BIT_STRING(3) ofs=0xD2 size=271
        0000  00 30 82 01 0A 02 82 01 01 00 D3 C8 A0 15 E6 24  |.0.............$|
        0010  45 18 C8 C8 26 0F 07 7F 87 CF 9C B3 28 71 BD E3  |E...&.......(q..|
        0020  90 D2 DC 0A 24 B8 43 42 8C B3 DA 0F F7 8B 8C 75  |....$.CB.......u|
        0030  69 3B 4D D6 1E 37 84 07 0C CD 99 DD 99 E2 6B 36  |i;M..7........k6|
        0040  00 EE 15 76 BA E7 1F E8 C9 C5 60 74 22 46 78 C1  |...v......`t"Fx.|
        0050  00 57 62 10 C5 BE 37 9B 2B 77 E5 67 55 07 7E 82  |.Wb...7.+w.gU.~.|
        0060  3D 8F 6B 32 0E D6 4D BB 42 4D 72 3A EE B8 5B 05  |=.k2..M.BMr:..[.|
        0070  58 EE 8C 9F F9 3C 32 8A 72 CC A4 9A 91 E9 DD A9  |X....<2.r.......|
        0080  B9 01 80 98 02 2A 12 D4 2A AB 29 42 3D 43 47 6A  |.....*..*.)B=CGj|
        0090  81 BD 58 D6 3A 5D 3E 8F F2 42 33 4D 20 33 B5 C8  |..X.:]>..B3M 3..|
        00A0  04 A0 16 F0 E5 15 29 1A 85 0D 0F AB 01 30 14 EF  |......)......0..|
        00B0  92 19 54 16 B4 F1 3F 9F 05 B3 63 F8 30 EA 50 BE  |..T...?...c.0.P.|
        00C0  3F 69 1D EA 12 86 7E D4 1D B9 BC CB 25 61 B7 1A  |?i....~.....%a..|
        00D0  04 C4 1A BF 57 84 F5 F7 23 B2 83 25 49 69 C3 8B  |....W...#..%Ii..|
        00E0  9C 78 4C CF 41 27 35 C9 93 71 10 B2 82 19 C7 FE  |.xL.A'5..q......|
        00F0  BE 8C 9D 47 82 22 0F D3 6F 34 AF 50 7D 5E A3 D6  |...G."..o4.P}^..|
        0100  A8 F1 3C 68 01 00 4F A7 57 3B 02 03 01 00 01 --  |..<h..O.W;......|
    7. Context-specific(3) composite ofs=0x1E5 size=928
      0. SEQUENCE(16) composite ofs=0x1E9 size=924
        0. SEQUENCE(16) composite ofs=0x1ED size=31
          0. OID=2.5.29.35 (Authority key identifier)
            0000  55 1D 23 -- -- -- -- -- -- -- -- -- -- -- -- --  |U.#.............|
          1. OCTET_STRING(4) ofs=0x1F4 size=24
            0000  30 16 80 14 12 C9 88 9B 2F C9 44 7A 7D 12 F1 DF  |0......./.Dz}...|
            0010  40 03 42 98 92 C7 24 D6 -- -- -- -- -- -- -- --  |@.B...$.........|
        1. SEQUENCE(16) composite ofs=0x20E size=29
          0. OID=2.5.29.14 (Subject key identifier)
            0000  55 1D 0E -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. OCTET_STRING(4) ofs=0x215 size=22
            0000  04 14 33 21 C5 6B 52 3E 5C 30 4C 87 99 28 99 A2  |..3!.kR>\0L..(..|
            0010  E9 F2 CC 35 26 F8 -- -- -- -- -- -- -- -- -- --  |...5&...........|
        2. SEQUENCE(16) composite ofs=0x22D size=51
          0. OID=2.5.29.17 (Subject alternative name)
            0000  55 1D 11 -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. OCTET_STRING(4) ofs=0x234 size=44
            0000  30 2A 82 09 2A 2E 72 73 64 6E 2E 72 75 82 0A 2A  |0*..*.rsdn.ru..*|
            0010  2E 72 73 64 6E 2E 6F 72 67 82 07 72 73 64 6E 2E  |.rsdn.org..rsdn.|
            0020  72 75 82 08 72 73 64 6E 2E 6F 72 67 -- -- -- --  |ru..rsdn.org....|
        3. SEQUENCE(16) composite ofs=0x262 size=14
          0. OID=2.5.29.15 (Key usage)
            0000  55 1D 0F -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. BOOLEAN(1) ofs=0x269 size=1
            0000  FF -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  |................|
          2. OCTET_STRING(4) ofs=0x26C size=4
            0000  03 02 05 A0 -- -- -- -- -- -- -- -- -- -- -- --  |................|
        4. SEQUENCE(16) composite ofs=0x272 size=29
          0. OID=2.5.29.37 (Certificate extension: extKeyUsage (Extended key usage))
            0000  55 1D 25 -- -- -- -- -- -- -- -- -- -- -- -- --  |U.%.............|
          1. OCTET_STRING(4) ofs=0x279 size=22
            0000  30 14 06 08 2B 06 01 05 05 07 03 01 06 08 2B 06  |0...+.........+.|
            0010  01 05 05 07 03 02 -- -- -- -- -- -- -- -- -- --  |................|
        5. SEQUENCE(16) composite ofs=0x291 size=159
          0. OID=2.5.29.31 (Certificate Revocation List distribution points)
            0000  55 1D 1F -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. OCTET_STRING(4) ofs=0x299 size=151
            0000  30 81 94 30 48 A0 46 A0 44 86 42 68 74 74 70 3A  |0..0H.F.D.Bhttp:|
            0010  2F 2F 63 72 6C 33 2E 64 69 67 69 63 65 72 74 2E  |//crl3.digicert.|
            0020  63 6F 6D 2F 47 65 6F 54 72 75 73 74 54 4C 53 44  |com/GeoTrustTLSD|
            0030  56 52 53 41 4D 69 78 65 64 53 48 41 32 35 36 32  |VRSAMixedSHA2562|
            0040  30 32 30 43 41 2D 31 2D 31 2E 63 72 6C 30 48 A0  |020CA-1-1.crl0H.|
            0050  46 A0 44 86 42 68 74 74 70 3A 2F 2F 63 72 6C 34  |F.D.Bhttp://crl4|
            0060  2E 64 69 67 69 63 65 72 74 2E 63 6F 6D 2F 47 65  |.digicert.com/Ge|
            0070  6F 54 72 75 73 74 54 4C 53 44 56 52 53 41 4D 69  |oTrustTLSDVRSAMi|
            0080  78 65 64 53 48 41 32 35 36 32 30 32 30 43 41 2D  |xedSHA2562020CA-|
            0090  31 2D 31 2E 63 72 6C -- -- -- -- -- -- -- -- --  |1-1.crl.........|
        6. SEQUENCE(16) composite ofs=0x333 size=62
          0. OID=2.5.29.32 (Certificate policies)
            0000  55 1D 20 -- -- -- -- -- -- -- -- -- -- -- -- --  |U. .............|
          1. OCTET_STRING(4) ofs=0x33A size=55
            0000  30 35 30 33 06 06 67 81 0C 01 02 01 30 29 30 27  |0503..g.....0)0'|
            0010  06 08 2B 06 01 05 05 07 02 01 16 1B 68 74 74 70  |..+.........http|
            0020  3A 2F 2F 77 77 77 2E 64 69 67 69 63 65 72 74 2E  |://www.digicert.|
            0030  63 6F 6D 2F 43 50 53 -- -- -- -- -- -- -- -- --  |com/CPS.........|
        7. SEQUENCE(16) composite ofs=0x373 size=133
          0. OID=1.3.6.1.5.5.7.1.1 (Certificate Authority Information Access)
            0000  2B 06 01 05 05 07 01 01 -- -- -- -- -- -- -- --  |+...............|
          1. OCTET_STRING(4) ofs=0x380 size=121
            0000  30 77 30 24 06 08 2B 06 01 05 05 07 30 01 86 18  |0w0$..+.....0...|
            0010  68 74 74 70 3A 2F 2F 6F 63 73 70 2E 64 69 67 69  |http://ocsp.digi|
            0020  63 65 72 74 2E 63 6F 6D 30 4F 06 08 2B 06 01 05  |cert.com0O..+...|
            0030  05 07 30 02 86 43 68 74 74 70 3A 2F 2F 63 61 63  |..0..Chttp://cac|
            0040  65 72 74 73 2E 64 69 67 69 63 65 72 74 2E 63 6F  |erts.digicert.co|
            0050  6D 2F 47 65 6F 54 72 75 73 74 54 4C 53 44 56 52  |m/GeoTrustTLSDVR|
            0060  53 41 4D 69 78 65 64 53 48 41 32 35 36 32 30 32  |SAMixedSHA256202|
            0070  30 43 41 2D 31 2E 63 72 74 -- -- -- -- -- -- --  |0CA-1.crt.......|
        8. SEQUENCE(16) composite ofs=0x3FB size=9
          0. OID=2.5.29.19 (Basic constraints)
            0000  55 1D 13 -- -- -- -- -- -- -- -- -- -- -- -- --  |U...............|
          1. OCTET_STRING(4) ofs=0x402 size=2
            0000  30 00 -- -- -- -- -- -- -- -- -- -- -- -- -- --  |0...............|
        9. SEQUENCE(16) composite ofs=0x406 size=383
          0. OID=1.3.6.1.4.1.11129.2.4.2 (Google.Extended validation certificates)
            0000  2B 06 01 04 01 D6 79 02 04 02 -- -- -- -- -- --  |+.....y.........|
          1. OCTET_STRING(4) ofs=0x416 size=367
            0000  04 82 01 6B 01 69 00 76 00 AD F7 BE FA 7C FF 10  |...k.i.v.....|..|
            0010  C8 8B 9D 3D 9C 1E 3E 18 6A B4 67 29 5D CF B1 0C  |...=..>.j.g)]...|
            0020  24 CA 85 86 34 EB DC 82 8A 00 00 01 7E 43 2A A0  |$...4.......~C*.|
            0030  CB 00 00 04 03 00 47 30 45 02 21 00 A6 27 AC FD  |......G0E.!..'..|
            0040  DB BE C0 84 DD C7 0C 70 B5 C1 C4 62 22 E0 5B 46  |.......p...b".[F|
            0050  4C 7B 5A B7 55 FF 67 B1 E3 C0 AC E5 02 20 4F F7  |L{Z.U.g...... O.|
            0060  18 91 58 A0 24 70 6B 5D 0D 86 A4 D2 35 AE 39 FC  |..X.$pk]....5.9.|
            0070  29 61 71 01 F0 7A EE 79 C0 B7 F2 2C 8A 2E 00 76  |)aq..z.y...,...v|
            0080  00 35 CF 19 1B BF B1 6C 57 BF 0F AD 4C 6D 42 CB  |.5.....lW...LmB.|
            0090  BB B6 27 20 26 51 EA 3F E1 2A EF A8 03 C3 3B D6  |..' &Q.?.*....;.|
            00A0  4C 00 00 01 7E 43 2A A0 BC 00 00 04 03 00 47 30  |L...~C*.......G0|
            00B0  45 02 20 24 47 8F AB B3 15 49 4E E4 71 0E 20 39  |E. $G....IN.q. 9|
            00C0  AA 13 B8 D0 95 63 69 36 6A CE C9 70 69 0F 86 4F  |.....ci6j..pi..O|
            00D0  88 CE 36 02 21 00 8F 60 AC 8D 27 98 AB 75 2C BB  |..6.!..`..'..u,.|
            00E0  F0 68 7A 84 20 2E 20 BD 49 64 5B 9D 11 1D 6F 35  |.hz. . .Id[...o5|
            00F0  EE 34 18 40 E6 29 00 77 00 B3 73 77 07 E1 84 50  |.4.@.).w..sw...P|
            0100  F8 63 86 D6 05 A9 DC 11 09 4A 79 2D B1 67 0C 0B  |.c.......Jy-.g..|
            0110  87 DC F0 03 0E 79 36 A5 9A 00 00 01 7E 43 2A A0  |.....y6.....~C*.|
            0120  F2 00 00 04 03 00 48 30 46 02 21 00 CB A6 E8 3E  |......H0F.!....>|
            0130  7E E2 39 5A F6 4C F6 0A 45 10 40 DB F0 1B FE 54  |~.9Z.L..E.@....T|
            0140  CB 15 6C 4D 44 78 E1 62 62 26 64 0E 02 21 00 D8  |..lMDx.bb&d..!..|
            0150  A0 CD 08 8A A7 E2 1F 56 08 D4 82 2A 97 CF B6 5C  |.......V...*...\|
            0160  FC 63 23 1E 6D 51 91 E0 50 7A 55 7D D7 52 6D --  |.c#.mQ..PzU}.Rm.|
  1. SEQUENCE(16) composite ofs=0x589 size=13
    0. OID=1.2.840.113549.1.1.11 (sha256WithRSAEncryption)
      0000  2A 86 48 86 F7 0D 01 01 0B -- -- -- -- -- -- --  |*.H.............|
    1. NULL(5) ofs=0x596 size=0
  2. BIT_STRING(3) ofs=0x598 size=257
    0000  00 36 BA 1F 2F 2D 1B 48 E4 B8 5D E5 02 AC D3 65  |.6../-.H..]....e|
    0010  1D 39 CA F9 19 E5 46 B2 C4 1F 21 A7 EE 01 A4 E1  |.9....F...!.....|
    0020  EF AF CA 7F 40 71 3C DC 10 7E F1 24 FD C9 16 F4  |....@q<..~.$....|
    0030  EC 0D 90 2D 83 87 4B F1 EA 06 64 EA CB 1D 6F 5F  |...-..K...d...o_|
    0040  BA 65 75 EA 6A 87 AA 4B 0C 0A E6 40 A3 43 F9 0A  |.eu.j..K...@.C..|
    0050  08 FD 50 E7 A9 A6 F0 1C 9E 5A AC 32 A1 7B 04 D2  |..P......Z.2.{..|
    0060  B6 00 2E 9F 33 4F 2D 11 E2 4A C4 AD FB E5 94 2E  |....3O-..J......|
    0070  B7 61 9E FF F7 27 FC 2B C1 B7 85 F7 55 DB C8 91  |.a...'.+....U...|
    0080  7C 8A 87 8D 5C FC 05 0B B6 08 89 5B C6 84 3A D5  ||...\......[..:.|
    0090  08 C2 E7 F7 13 C2 02 15 AE 4E 91 F0 F7 00 EE D0  |.........N......|
    00A0  20 88 E7 D8 26 C5 01 E8 7B DA 3A AD CC 73 3D E7  | ...&...{.:..s=.|
    00B0  06 A6 62 C8 E2 88 79 D5 36 BB 59 00 05 84 A3 2C  |..b...y.6.Y....,|
    00C0  32 57 88 8A 78 39 B3 4F 7F C6 5D FE AB 56 7C B4  |2W..x9.O..]..V|.|
    00D0  CE 87 BA C1 62 39 A2 D1 F0 2D 5F EE E4 04 EF 58  |....b9...-_....X|
    00E0  B5 52 0C 65 2D AA 38 7A 19 28 03 38 6E 3F 4D DD  |.R.e-.8z.(.8n?M.|
    00F0  31 2D E9 CA 0C 8C 9C E0 39 9E BA 7A C9 65 7E B2  |1-......9..z.e~.|
    0100  CF -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  |................|

ps: oid-ы можно тут глянуть, но там далеко не все.
Их количество не ограничено и любая организация может нагенерировать их в любых масштабах.
Отредактировано 03.06.2022 21:01 kov_serg . Предыдущая версия . Еще …
Отредактировано 03.06.2022 20:51 kov_serg . Предыдущая версия .
Отредактировано 03.06.2022 20:34 kov_serg . Предыдущая версия .
Отредактировано 03.06.2022 20:33 kov_serg . Предыдущая версия .
Отредактировано 03.06.2022 20:30 kov_serg . Предыдущая версия .
Отредактировано 03.06.2022 20:27 kov_serg . Предыдущая версия .
Отредактировано 03.06.2022 20:26 kov_serg . Предыдущая версия .
Отредактировано 03.06.2022 20:20 kov_serg . Предыдущая версия .
Отредактировано 03.06.2022 19:08 kov_serg . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.