DER Parser

Tarun Upadhyay tarun@ebprovider.com
Sat, 12 Aug 2000 13:42:57 +0530


This is a multi-part message in MIME format.

------=_NextPart_000_0200_01C00463.3968D960
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hi all,

I have just completed a DER Certificate Parser in Flex.
For the want of CVS access, I am sending it attached for review (hopefully,
there are not too many people on the list !!)
Currently the display is not indented but I will do that asap

To Do List:
1. move the parser out of Flex and into 'real' C.
2. check it for bugs and add support for indented display.
3. provide interface to allow function calls to be made to read a particular
attribute of the certificate. (somewhat like cert in SSLeay)
4. may be provide a DER2XML utility.

I plan to do all this by the next weekend.
If anybody could point me to a few assorted DER certificates for debugging
and testing, I will be obliged.

With Warm Regards
Tarun Upadhyay
http://ebprovider.com/people/tarun

------=_NextPart_000_0200_01C00463.3968D960
Content-Type: application/octet-stream;
	name="cert.lex"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="cert.lex"

/* scanner for DER encoded certificates */

/*
 *      Copyright (C) 2000 Tarun Upadhyay <tarun@ebprovider.com>
 *
 * This file is part of GNUTLS.
 *
 * GNUTLS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * GNUTLS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, =
USA
 */

%{ =20
  /* C declarations block */
#define CHOP(C) ((c)&'\x7f')

  unsigned long size;
  unsigned long levels[64];
  int current =3D 0;
  unsigned long realsize;
 =20
  void parselen(void){
    int i;
    char c;
    printf("\tLEN: ");
    c =3D input();
    realsize =3D 2;
    if (c & '\x80') {
      printf("%d/", CHOP(c));
      realsize +=3D CHOP(c);
      for (size=3D0, i =3D 0; i < CHOP(c); i++){
	size <<=3D 8;
	size +=3D input();
      }
    }
    else
      size =3D c;
    realsize +=3D size;
    printf("%d ", size);
  }

  void increaselevel(void){
    levels[current++] =3D realsize;
    levels[current] =3D 0;
  }

  void checklevel(void){
    levels[current] +=3D realsize;
    if (levels[current] =3D=3D levels[current-1])
  }
%}

%%

\x01 {
  printf("\nBOOLEAN");
  input();
  printf("%d ", input());
}

\x02 {
  int i;
  printf("\nINTEGER");
  parselen();
  for (i =3D 0; i < size; i++)
    printf("%x ", input());
  size =3D 0;
}

\x03 |
\x04 {
  int i;
  printf("\nBIT STRING");
  parselen();
  for (i =3D 0; i < size ; i++)
    printf("%x ", input());
  size =3D 0;
}

\x05 {
  printf("\nNULL");
  input();
}

\x06 {
  int i;
  printf("\nOID");
  parselen();
  for (i =3D 0; i < size ; i++)
    printf("%x.", input());
  size =3D 0;
}

\x13 |
\x16 {
  int i;
  printf("\nSTRING");
  parselen();
  for (i =3D 0; i < size ; i++)
    printf("%c", input());
  size =3D 0;
}

\x17 {
  char c;
  printf("\nUTC TIME");
  parselen();
  c =3D input();

  /* year */
  if (c <=3D '4')
    printf("20");
  else
    printf("19");
  printf("%c", c);
  printf("%c", input());
 =20
  /* month */
  printf("/%c", input());
  printf("%c", input());

  /* day */
  printf("/%c", input());
  printf("%c", input());

  /* hours */
  printf(" %c", input());
  printf("%c", input());

  /* minutes */
  printf(":%c", input());
  printf("%c", input());

  /* seconds */
  printf(":%c", input());
  printf("%c", input());

  input();
}

[\xa0-\xaf] {
  int i;
  printf("\nARRAY[%d]", yytext[0] & '\x07');
  parselen();
  increaselevel();
}

\x30 {
  printf("\nSEQUENCE");
  parselen();
  increaselevel();
}

\x31 {
  printf("\nSET");
  parselen();
  increaselevel();
}

%%

main (int argc, char ** argv){
  yyin =3D stdin;
  yylex();
  printf("\n");
}


------=_NextPart_000_0200_01C00463.3968D960--