anterior índice siguiente

Certificados X509 y objetos PKCS 10

En cualquier caso, hemos de pensar que una persona no se hace su certificado X509 (excepto si lo hace autofirmado, siendo esa persona mismo titular y autoridad certificadora). Es la Autoridad Certificadora quien recibe una petición de certificado y firma esa petición, creando un nuevo objeto x509 a partir de los datos de la petición y otros que posee la autoridad.

La Forma que tiene una persona de pedir un certificado es a través de un objeto PKCS 10 o también conocido como Petición de certificado (CSR, certificate signing request). Es misión de la autoridad certificadora asegurarse de los datos que certifica, de lo contrario sus certificados tendrían una validez pésima.

Para poder gestionar los objetos PKCS 10 y los X509, openssl proporciona dos funciones para pasar del uno al otro y viceversa. Estas funciones son:

La tercera función la utilizamos para mostrar por pantalla el certificado creado, pues al no estar completo el certificado , no puede ser mostrado por medio de la línea de comando mediante openssl. ¡Tranquilos, ya haremos un certificado completo dentro de muy poco!. En el caso de que tengamos una petición para crear un objeto X509 a partir de un objeto PKCS 10 podemos ver el ejemplo 11

// Este ejemplo carga un PKCS10 y lo transforma en un objeto X509
//
// La sintaxis es:
//			req2x509 fich_req clave_req fich_x509
//
//      Ejemplo realizado por Jose Traver - jose@nisu.org


#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char ** argv)
{
   EVP_PKEY *evp=NULL;
   FILE *fp_cert, *fp_req, *fp_clave;
   X509 * x=NULL;
   X509_REQ * req=NULL;
   int resultado;

   // Abrimos el fichero del X509
   if ((fp_req =fopen(argv[3],"w")) == NULL) {
        perror("ERROR al leer el fichero con el certificado");
        exit(1);
   }

   // Abrimos el fichero de la clave
   if ((fp_clave = fopen (argv[2],"r")) == NULL ){
        perror("ERROR al leer la clave privada");
        exit(1);
   }

   // Abrimos el fichero del PKCS10
   if ((fp_cert = fopen (argv[1],"r")) == NULL ){
        perror("ERROR al abrir el fichero de salida");
        exit(1);
   }

   // leemos el certificado

   req=X509_REQ_new();
   req = PEM_read_X509_REQ (fp_cert,NULL,NULL,NULL);
   printf("Certificado  leido\n");

   // Leemos la clave privada

   evp=EVP_PKEY_new();
   PEM_read_PrivateKey(fp_clave,&evp,NULL,NULL);
   printf("Clave leida\n");

   // Transformamos la peticion de certificado PKCS10 en certificado X509

   x=X509_new();
   x=X509_REQ_to_X509(req,(int)20,evp);

   // Escribimos el certificado

   PEM_write_X509(fp_req,x);   
   printf("X509 REQ escrito\n");   
   X509_print_fp(stdout,x);



   fclose(fp_req);
   fclose(fp_cert);
   fclose(fp_clave);

   EVP_PKEY_free(evp);
   X509_free(x);
   X509_REQ_free(req);

}

Ejemplo 11. Conversión de un objeto PKCS10 a un objeto X509

Sin embargo, también podemos hacer el paso contrario y obtener la petición de certificado a partir del propio certificado X509, como podemos ver en el ejemplo 12.



// Este ejemplo carga un X509 y lo transforma en un objeto PKCS10
//
// La sintaxis es:
//			x5092req fich_x509 clave_x509 fich_req
//
//      Ejemplo realizado por Jose Traver - jose@nisu.org


#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char ** argv)
{
   EVP_PKEY *evp=NULL;
   FILE *fp_cert, *fp_req, *fp_clave;
   X509 * x=NULL;
   X509_REQ * req=NULL;
   int resultado;

   // Abrimos el fichero del PKCS10
   if ((fp_req =fopen(argv[3],"w")) == NULL) {
        perror("ERROR al abrir el fichero de salida");
        exit(1);
   }

   // Abrimos el fichero de la clave
   if ((fp_clave = fopen (argv[2],"r")) == NULL ){
        perror("ERROR al leer la clave privada");
        exit(1);
   }

   // Abrimos el fichero del X509
   if ((fp_cert = fopen (argv[1],"r")) == NULL ){
        perror("ERROR al abrir el fichero de certificado");
        exit(1);
   }

   // Leemos el certificado

   x=X509_new();
   x = PEM_read_X509 (fp_cert,NULL,NULL,NULL);
   printf("Certificado  leido\n");

   // Leemos la clave privada

   evp=EVP_PKEY_new();
   PEM_read_PrivateKey(fp_clave,&evp,NULL,NULL);
   printf("Clave leida\n");

   // Transformamos el certificado X509 en PKCS10

   req=X509_REQ_new();
   req=X509_to_X509_REQ(x,evp,EVP_md5());

   // Escribimos el PKCS 10

   PEM_write_X509_REQ(fp_req,req);   
   printf("X509 REQ escrito\n");   
   X509_REQ_print_fp(stdout,req);

   fclose(fp_req);
   fclose(fp_cert);
   fclose(fp_clave);
  
   X509_free(x);
   X509_REQ_free(req);
   EVP_PKEY_free(evp);
 
}


Ejemplo 12. Conversión de un objeto X509 a un objeto PKCS 10

Ojo, porque el x509 del ejemplo 11 no es un certificado completo, pues faltan datos por rellenar en la estructura y firmarlo, pero el objeto PKCS 10 del ejemplo 12 si que es perfectamente válido, pues todos los campos de su estructura han sido rellenados a partir de los valores que ya exixten en el certificado X509.


anterior índice siguiente