// En este ejemplo vamos a crear un certificado completo autofirmado.
// La sintaxis es:
// cert_completo fich_cert fich_key numbitsRSA numserie dias_valido
//
// fich_cert : Nombre del fichero de salida del certificado X509
// fich_key : Nombre del fichero de salida de la clave privada
// numbitsRSA : Numero de bits de las claves RSA
// numserie : Numero de serie del certificado
// dias_valido : Numero de dias de validez del certificado
//
// Ejemplo creado por Jose Traver - jose@nisu.org
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char ** argv)
{
FILE * fp_cert,*fp_clave;
X509 * x=NULL;
EVP_PKEY * clave=NULL;
RSA * rsa;
X509_NAME * nombre=NULL;
int Nserie;
int Nrsa;
int Ndias;
// Abrimos el fichero para escritura del certificado
if ((fp_cert =fopen(argv[1],"w")) == NULL) {
perror("ERROR al abrir el fichero del certificado");
exit(1);
}
// Abrimos el fichero para escritura de la clave privada
if ((fp_clave =fopen(argv[2],"w")) == NULL) {
perror("ERROR al abrir el fichero de la clave privada");
exit(1);
}
// Recogida de datos de los parametros
Nserie = atoi(argv[4]);
Nrsa = atoi(argv[3]);
Ndias = atoi(argv[5]);
// Iniciación de variables y estructuras del programa
x = X509_new();
clave = EVP_PKEY_new();
// Generación del par de llaves RSA
rsa=RSA_generate_key(Nrsa,RSA_F4,NULL,NULL);
// Asignación del par RSA a la estructura de clave privada EVP_PKEY
EVP_PKEY_assign_RSA(clave,rsa);
// Relleno de datos del certificado
X509_set_version(x,3);
ASN1_INTEGER_set(X509_get_serialNumber(x),Nserie);
X509_gmtime_adj(X509_get_notBefore(x),0);
X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*Ndias);
X509_set_pubkey(x,clave);
// Relleno de nombres del certificado. Esto podria hacerse de varias formas:
// * Interactuando con el usuario
// * Leyendo la información de un fichero
// Ya que es solo un ejemplo, los ponemos a mano y vale, pero el sistema es
// bien sencillo, solo se necesita obtener cadenas de caracteres.
nombre=X509_get_subject_name(x);
X509_NAME_add_entry_by_txt(nombre,"C",MBSTRING_ASC, "ES", -1, -1, 0);
X509_NAME_add_entry_by_txt(nombre,"ST",MBSTRING_ASC, "CS", -1, -1, 0);
X509_NAME_add_entry_by_txt(nombre,"L",MBSTRING_ASC, "Cs", -1, -1, 0);
X509_NAME_add_entry_by_txt(nombre,"O",MBSTRING_ASC, "Mi organizacion", -1, -1, 0);
X509_NAME_add_entry_by_txt(nombre,"OU",MBSTRING_ASC, "Mi departamento", -1, -1, 0);
X509_NAME_add_entry_by_txt(nombre,"CN",MBSTRING_ASC, "Mi nombre", -1, -1, 0);
X509_NAME_add_entry_by_txt(nombre,"Email",MBSTRING_ASC, "nombre@dir.dom", -1, -1, 0);
X509_set_issuer_name(x,nombre);
// Firmamos el certificado que hemos creado con nuestra propia clave
X509_sign(x,clave,EVP_md5());
// Podemos imprimir por pantalla el resultado del certificado y la clave
RSA_print_fp(stdout,clave->pkey.rsa,0);
X509_print_fp(stdout,x);
// Escribimos el certificado y la clave privada en los ficheros especificados
PEM_write_X509(fp_cert,x);
PEM_write_PrivateKey(fp_clave,clave,NULL,NULL,0,NULL, NULL);
// Cerramos ficheros y liberamos de la memoria las estructuras usadas
fclose(fp_cert);
fclose(fp_clave);
X509_free(x);
EVP_PKEY_free(clave);
}
|