LogoSearch packages:      

Sourcecode: libtasn1-2 version File versions

CertificateExample.c

/*
 *      Copyright (C) 2000,2001 Fabio Fiorina
 *
 * 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
 */


/*****************************************************/
/* File: CertificateExample.c                        */
/* Description: An example on how to use the ASN1    */
/*              parser with the Certificate.txt file */   
/*****************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "libtasn1.h"


char *
my_ltostr(long v,char *str)
{
  long d,r;
  char temp[20];
  int count,k,start;

  if(v<0){
    str[0]='-';
    start=1;
    v=-v;
  }
  else start=0;

  count=0;
  do{
    d=v/10;
    r=v-d*10;
    temp[start+count]='0'+(char)r;
    count++;
    v=d;
  }while(v);

  for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
  str[count+start]=0;
  return str;
}

/******************************************************/
/* Function : get_name_type                           */
/* Description: analyze a structure of type Name      */
/* Parameters:                                        */
/*   char *root: the structure identifier             */
/*   char *answer: the string with elements like:     */
/*                 "C=US O=gov"                       */ 
/******************************************************/
void
get_Name_type(node_asn *cert_def,node_asn *cert,char *root, char *answer)
{
  int k,k2,result,len;
  char name[128],str[1024],str2[1024],name2[128],counter[5],name3[128];
  ASN1_TYPE value=ASN1_TYPE_EMPTY;
  char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];

  answer[0]=0;
  k=1;
  do{
    strcpy(name,root);
    strcat(name,".rdnSequence.?");
    my_ltostr(k,counter);
    strcat(name,counter);
    len = sizeof(str) - 1;
    result=asn1_read_value(cert,name,str,&len);
    if(result==ASN1_ELEMENT_NOT_FOUND) break;
    k2=1;
    do{
      strcpy(name2,name);
      strcat(name2,".?");
      my_ltostr(k2,counter);
      strcat(name2,counter);
      len = sizeof(str) - 1;
      result=asn1_read_value(cert,name2,str,&len);
      if(result==ASN1_ELEMENT_NOT_FOUND) break;
      strcpy(name3,name2);
      strcat(name3,".type");
      len = sizeof(str) - 1;
      result=asn1_read_value(cert,name3,str,&len);
      strcpy(name3,name2);
      strcat(name3,".value");
      if(result==ASN1_SUCCESS){
      len = sizeof(str2) - 1;
      result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",
                    str2,&len);
      if(!strcmp(str,str2)){
        asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
                     &value);
        len = sizeof(str) - 1;
        asn1_read_value(cert,name3,str,&len);
              asn1_der_decoding(&value,str,len,errorDescription);
        len = sizeof(str) - 1;
        asn1_read_value(value,"",str,&len);  /* CHOICE */
        strcpy(name3,str);
        len = sizeof(str) - 1;
        asn1_read_value(value,name3,str,&len);
        str[len]=0;
        strcat(answer," C=");
        strcat(answer,str);
        asn1_delete_structure(&value);
      }
      else{
        len = sizeof(str2) - 1;
        result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName"
                      ,str2,&len);
        if(!strcmp(str,str2)){
          asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName"
                       ,&value);
          len = sizeof(str) - 1;
          asn1_read_value(cert,name3,str,&len);   
          asn1_der_decoding(&value,str,len,errorDescription);
          len = sizeof(str) - 1;
          asn1_read_value(value,"",str,&len);  /* CHOICE */
          strcpy(name3,str);
          len = sizeof(str) - 1;
          asn1_read_value(value,name3,str,&len);
          str[len]=0;
          strcat(answer," O=");
          strcat(answer,str);
          asn1_delete_structure(&value);
        }
        else{
          len = sizeof(str2) - 1;
          result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",str2,&len);
          if(!strcmp(str,str2)){
            asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
            len = sizeof(str) - 1;
            asn1_read_value(cert,name3,str,&len);
            asn1_der_decoding(&value,str,len,errorDescription);
            len = sizeof(str) - 1;
            asn1_read_value(value,"",str,&len);  /* CHOICE */
            strcpy(name3,str);
            len = sizeof(str) - 1;
            asn1_read_value(value,name3,str,&len);
            str[len]=0;
            strcat(answer," OU=");
            strcat(answer,str);
            asn1_delete_structure(&value);
          }
        }
      }
      }
      k2++;
    }while(1);
    k++;
  }while(1);
}


/******************************************************/
/* Function : create_certificate                      */
/* Description: creates a certificate named           */
/*              "certificate1". Values are the same   */
/*              as in rfc2459 Appendix D.1            */
/* Parameters:                                        */
/*   unsigned char *der: contains the der encoding    */
/*   int *der_len: number of bytes of der string      */ 
/******************************************************/
void
create_certificate(node_asn *cert_def,unsigned char *der,int *der_len)
{
  int result,k,len;
  unsigned char str[1024],*str2;
  ASN1_TYPE cert1=ASN1_TYPE_EMPTY;
  ASN1_TYPE value=ASN1_TYPE_EMPTY;
  ASN1_TYPE param=ASN1_TYPE_EMPTY;
  ASN1_TYPE constr=ASN1_TYPE_EMPTY;
  char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
  int max_len;

  max_len=*der_len;

  result=asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert1);
 
  /* Use the next 3 lines to visit the empty certificate */
  /* printf("-----------------\n");
     asn1_visit_tree(cert1,"");   
     printf("-----------------\n"); */

  /* version: v3(2) */  
  result=asn1_write_value(cert1,"tbsCertificate.version","v3",0); 

  /* serialNumber: 17 */    
  result=asn1_write_value(cert1,"tbsCertificate.serialNumber","17",0); 

  /* signature: dsa-with-sha1 */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.signature.algorithm",
                 str,1);    
  
  result=asn1_write_value(cert1,"tbsCertificate.signature.parameters",
                 NULL,0);


  /* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
  result=asn1_write_value(cert1,"tbsCertificate.issuer","rdnSequence",12);

  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
  /* C */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
  result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
                    &value);
  result=asn1_write_value(value,"","US",2);
  *der_len = max_len;
  result=asn1_der_coding(value,"",der,der_len,errorDescription);
  asn1_delete_structure(&value);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);


  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
  /* O */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
  result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
                    &value);
  result=asn1_write_value(value,"","printableString",1);
  result=asn1_write_value(value,"printableString","gov",3);
  *der_len = max_len;
  result=asn1_der_coding(value,"",der,der_len,errorDescription);
  asn1_delete_structure(&value);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);


  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence","NEW",1);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);

  /* OU */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
                str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type",str,1);
  result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
  result=asn1_write_value(value,"","printableString",1);
  result=asn1_write_value(value,"printableString","nist",4);
  *der_len = max_len;
  result=asn1_der_coding(value,"",der,der_len,errorDescription);
  asn1_delete_structure(&value);
  result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);


  /* validity */
  result=asn1_write_value(cert1,"tbsCertificate.validity.notBefore","utcTime",1);
  result=asn1_write_value(cert1,"tbsCertificate.validity.notBefore.utcTime","970630000000Z",1);

  result=asn1_write_value(cert1,"tbsCertificate.validity.notAfter","utcTime",1);
  result=asn1_write_value(cert1,"tbsCertificate.validity.notAfter.utcTime","971231000000Z",1);



  /* subject: Country="US" Organization="gov" OrganizationUnit="nist" */
  result=asn1_write_value(cert1,"tbsCertificate.subject","rdnSequence",1);

  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",1);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
  /* C */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-countryName",str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
  result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
                    &value);
  result=asn1_write_value(value,"","US",2);
  *der_len = max_len;
  result=asn1_der_coding(value,"",der,der_len,errorDescription);
  asn1_delete_structure(&value);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);


  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",4);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
  /* O */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationName",str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
  result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationName",
                    &value);
  result=asn1_write_value(value,"","printableString",1);
  result=asn1_write_value(value,"printableString","gov",3);
  *der_len = max_len;
  result=asn1_der_coding(value,"",der,der_len,errorDescription);
  asn1_delete_structure(&value);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);


  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence","NEW",4);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
  /* OU */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-at-organizationalUnitName",
                str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.type",str,1);
  result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
  result=asn1_write_value(value,"","printableString",1);
  result=asn1_write_value(value,"printableString","nist",4);
  *der_len = max_len;
  result=asn1_der_coding(value,"",der,der_len,errorDescription);
  asn1_delete_structure(&value);
  result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);


  /* subjectPublicKeyInfo: dsa with parameters=Dss-Parms */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa",str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",str,1); 
  result=asn1_create_element(cert_def,"PKIX1Implicit88.Dss-Parms",&param);
  str2="\xd4\x38"; /* only an example */
  result=asn1_write_value(param,"p",str2,128);
  str2="\xd4\x38"; /* only an example */
  result=asn1_write_value(param,"q",str2,20);
  str2="\xd4\x38"; /* only an example */
  result=asn1_write_value(param,"g",str2,128);
  *der_len = max_len;
  result=asn1_der_coding(param,"",der,der_len,errorDescription);
  asn1_delete_structure(&param);
  result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",der,*der_len); 


  /* subjectPublicKey */
  str2="\x02\x81"; /* only an example */
  result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",str2,1048);

  result=asn1_write_value(cert1,"tbsCertificate.issuerUniqueID",NULL,0);  /* NO OPTION */
  result=asn1_write_value(cert1,"tbsCertificate.subjectUniqueID",NULL,0); /* NO OPTION */

  /* extensions */
  result=asn1_write_value(cert1,"tbsCertificate.extensions","NEW",1); 
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-basicConstraints",
                str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnID",str,1); /*   basicConstraints */  
  result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.critical","TRUE",1); 
  result=asn1_create_element(cert_def,"PKIX1Implicit88.BasicConstraints",&constr);
  result=asn1_write_value(constr,"cA","TRUE",1); 
  result=asn1_write_value(constr,"pathLenConstraint",NULL,0); 
  *der_len = max_len; 
  result=asn1_der_coding(constr,"",der,der_len,errorDescription);
  result=asn1_delete_structure(&constr);
  result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",der,*der_len); 


  result=asn1_write_value(cert1,"tbsCertificate.extensions","NEW",1); 
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-ce-subjectKeyIdentifier",
                str,&len);
  result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnID",str,1); /* subjectKeyIdentifier */ 
  result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.critical","FALSE",1); 
  str2="\x04\x14\xe7\x26\xc5"; /* only an example */
  result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",str2,22); 


  /* signatureAlgorithm: dsa-with-sha  */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str,&len);
  result=asn1_write_value(cert1,"signatureAlgorithm.algorithm",str,1); 
  result=asn1_write_value(cert1,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */  


  /* signature */
  *der_len = max_len;
  result=asn1_der_coding(cert1,"tbsCertificate",der,der_len
                         ,errorDescription);
  if(result!=ASN1_SUCCESS){
    printf("\n'tbsCertificate' encoding creation: ERROR\n");
  }
  /* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
  result=asn1_write_value(cert1,"signature",str2,368); /* dsa-with-sha */ 
  

  /* Use the next 3 lines to visit the certificate */
  /* printf("-----------------\n");   
     asn1_visit_tree(cert1,"");  
     printf("-----------------\n"); */

  *der_len = max_len;
  result=asn1_der_coding(cert1,"",der,der_len,errorDescription);
  if(result!=ASN1_SUCCESS){
    printf("\n'certificate' encoding creation: ERROR\n");
    return;
  }

  /* Print the 'Certificate1' DER encoding */ 
  printf("-----------------\nCertificate Encoding:\nNumber of bytes=%i\n",*der_len);
  for(k=0;k<*der_len;k++) printf("%02x ",der[k]);  
  printf("\n-----------------\n");

  /* Clear the "certificate1" structure */
  asn1_delete_structure(&cert1);
}



/******************************************************/
/* Function : get_certificate                         */
/* Description: creates a certificate named           */
/*              "certificate2" from a der encoding    */
/*              string                                */
/* Parameters:                                        */
/*   unsigned char *der: the encoding string          */
/*   int der_len: number of bytes of der string      */ 
/******************************************************/
void
get_certificate(node_asn *cert_def,unsigned char *der,int der_len)
{
  int result,len,start,end;
  unsigned char str[1024],str2[1024];
  ASN1_TYPE cert2=ASN1_TYPE_EMPTY;
  char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];

  asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert2);

  result=asn1_der_decoding(&cert2,der,der_len,errorDescription);

  if(result!=ASN1_SUCCESS){
    printf("Problems with DER encoding\n");
    return;
  }
   

  /* issuer */
  get_Name_type(cert_def,cert2,"tbsCertificate.issuer",str);
  printf("certificate:\nissuer :%s\n",str);
  /* subject */
  get_Name_type(cert_def,cert2,"tbsCertificate.subject",str);
  printf("subject:%s\n",str);


  /* Verify sign */
  len = sizeof(str) - 1;
  result=asn1_read_value(cert2,"signatureAlgorithm.algorithm"
                ,str,&len);

  len = sizeof(str2) - 1;
  result=asn1_read_value(cert_def,"PKIX1Implicit88.id-dsa-with-sha1",str2,&len);
  if(!strcmp(str,str2)){  /* dsa-with-sha */

    result=asn1_der_decoding_startEnd(cert2,der,der_len,
                       "tbsCertificate",&start,&end);

    /* add the lines to calculate the sha on der[start]..der[end] */

    len = sizeof(str) - 1;
    result=asn1_read_value(cert2,"signature",str,&len);

    /* compare the previous value to signature ( with issuer public key) */ 
  }

  /* Use the next 3 lines to visit the certificate */
  /*   printf("-----------------\n");   
     asn1_visit_tree(cert2,"");  
     printf("-----------------\n"); */


  /* Clear the "certificate2" structure */
  asn1_delete_structure(&cert2);
}

#include "pkix_asn1_tab.c"

/********************************************************/
/* Function : main                                      */
/* Description: reads the certificate description.      */
/*              Creates a certificate and calculate     */
/*              the der encoding. After that creates    */  
/*              another certificate from der string     */
/********************************************************/
int
main(int argc,char *argv[])
{
  int result,der_len;
  unsigned char der[1024];
  ASN1_TYPE PKIX1Implicit88=ASN1_TYPE_EMPTY;
  char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];

  if(1)
    result=asn1_array2tree(pkix_asn1_tab,&PKIX1Implicit88,errorDescription); 
  else
    result=asn1_parser2tree("pkix.asn",&PKIX1Implicit88,errorDescription);

  if(result != ASN1_SUCCESS){
    libtasn1_perror(result);
    printf("%s",errorDescription);
    exit(1);
  }

  
  /* Use the following 3 lines to visit the PKIX1Implicit structures */
  /* printf("-----------------\n");
     asn1_visit_tree(PKIX1Implicit88,"PKIX1Implicit88");   
     printf("-----------------\n"); */

  der_len=1024;
  create_certificate(PKIX1Implicit88,der,&der_len);

  get_certificate(PKIX1Implicit88,der,der_len);

  /* Clear the "PKIX1Implicit88" structures */
  asn1_delete_structure(&PKIX1Implicit88);

  return 0;
}










Generated by  Doxygen 1.5.1   Back to index