Пример #1
0
unsigned __stdcall signTest( void *arg ) 
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CONTEXT privateKeyContext;
	CRYPT_ENVELOPE cryptEnvelope;
	BYTE buffer[ 1024 ];
	const int count = *( ( int * ) arg );
	int bytesCopied, i, status;

	printf( "SignTest %d.\n", count );

	for( i = 0; i < count; i++ ) 
		{
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, 
								  CRYPT_KEYSET_FILE, TEST_PRIVKEY_FILE, 
								  CRYPT_KEYOPT_READONLY);
		if( cryptStatusOK( status ) )
			status = cryptGetPrivateKey( cryptKeyset, &privateKeyContext, 
										 CRYPT_KEYID_NAME, RSA_PRIVKEY_LABEL, 
										 TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, 
										  CRYPT_FORMAT_CMS );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_SIGNATURE, 
										privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, "message", 7, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptFlushData( cryptEnvelope );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, buffer, 1024, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyContext( privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptKeysetClose( cryptKeyset );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			_endthreadex( status );
			return( 0 );
			}
		}

	_endthreadex( 0 );
	return( 0 );
	}
Пример #2
0
static int exec_gencrl(int argc, char **argv) {
  CRYPT_KEYSET cakeys, store;
  CRYPT_CERTIFICATE crl;
  CRYPT_CONTEXT ca_privkey;
  const char *dbfilename;
  char cakeysfilename[4096];
  int status;
  if (argc < 2) { fprintf(stderr, "missing dbfilename/outfilename\n"); return 1; }
  dbfilename = argv[0];

  /* open store */
  status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);

  /* get ca privkey */
  snprintf(cakeysfilename, 4095, "%s.keys", dbfilename);
  cakeysfilename[4095] = '\0';
  status = cryptKeysetOpen(&cakeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cakeysfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);
  status = cryptGetPrivateKey(cakeys, &ca_privkey, CRYPT_KEYID_NAME, DEFAULT_CA_PRIVKEY_LABEL, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(cakeys);
  WARN_AND_RETURN_IF(status);

  status = cryptCACertManagement(&crl, CRYPT_CERTACTION_ISSUE_CRL, store, ca_privkey, CRYPT_UNUSED);
  WARN_AND_RETURN_IF(status);

  status = export_cert(crl, argv[1]);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(crl);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(store);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyContext(ca_privkey);
  WARN_AND_RETURN_IF(status);
  return 0;
}
Пример #3
0
const char *signCMS(
    struct CMS *cms,
    const char *keyfilename,
    bool bad)
{
    bool hashContext_initialized = false;
    CRYPT_CONTEXT hashContext;
    bool sigKeyContext_initialized = false;
    CRYPT_CONTEXT sigKeyContext;
    CRYPT_KEYSET cryptKeyset;
    int signatureLength;
    int tbs_lth;
    char *msg = (char *)0;
    uchar *tbsp;
    uchar *signature = NULL;
    uchar hash[40];
    struct casn *sidp;
    struct Attribute *attrp;
    struct AttrTableDefined *attrtdp;
    struct SignerInfo *sigInfop;

    // signer info
    // firat clear out any old stuff in signerInfos that may have been put
    // there by old code
    while (num_items(&cms->content.signedData.signerInfos.self) > 0)
        eject_casn(&cms->content.signedData.signerInfos.self, 0);
    sigInfop =
        (struct SignerInfo *)
        inject_casn(&(cms->content.signedData.signerInfos.self), 0);

    // write the signature version (3) to the signer info
    write_casn_num(&sigInfop->version.self, 3);

    // find the SID
    if ((sidp = findSID(cms)) == NULL)
        return "finding SID";

    // copy the CMS's SID over to the signature's SID
    copy_casn(&sigInfop->sid.subjectKeyIdentifier, sidp);

    // use sha256 as the algorithm
    write_objid(&sigInfop->digestAlgorithm.algorithm, id_sha256);

    // no parameters to sha256
    write_casn(&sigInfop->digestAlgorithm.parameters.sha256, (uchar *) "", 0);

    // first attribute: content type
    attrp = (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 0);
    write_objid(&attrp->attrType, id_contentTypeAttr);
    attrtdp =
        (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0);
    copy_casn(&attrtdp->contentType,
              &cms->content.signedData.encapContentInfo.eContentType);

    // second attribute: message digest
    attrp = (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 1);
    write_objid(&attrp->attrType, id_messageDigestAttr);

    // create the hash for the content

    // first pull out the content
    if ((tbs_lth =
         readvsize_casn(&cms->content.signedData.encapContentInfo.eContent.
                        self, &tbsp)) < 0)
        return "getting content";

    // set up the context, initialize crypt
    memset(hash, 0, 40);
    if (cryptInit_wrapper() != CRYPT_OK)
        return "initializing cryptlib";

    // the following calls function f, and if f doesn't return 0 sets
    // msg to m, then breaks out of the loop. Used immediately below.
#define CALL(f,m) if (f != 0) { msg = m; break; }

    // use a "do { ... } while (0)" loop to bracket this code, so we can
    // bail out on failure. (Note that this construct isn't really a
    // loop; it's a way to use break as a more clean version of goto.)
    do
    {
        // first sign the body of the message

        // create the context
        CALL(cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2),
             "creating context");
        hashContext_initialized = true;

        // generate the hash
        CALL(cryptEncrypt(hashContext, tbsp, tbs_lth), "hashing");
        CALL(cryptEncrypt(hashContext, tbsp, 0), "hashing");

        // get the hash value. then we're done, so destroy it
        CALL(cryptGetAttributeString
             (hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &signatureLength),
             "getting first hash");
        CALL(cryptDestroyContext(hashContext),
             "destroying intermediate context");

        // insert the hash as the first attribute
        attrtdp =
            (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0);
        write_casn(&attrtdp->messageDigest, hash, signatureLength);

        // create signing time attribute; mark the signing time as now
        if (getenv("RPKI_NO_SIGNING_TIME") == NULL)
        {
            attrp =
                (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 2);
            write_objid(&attrp->attrType, id_signingTimeAttr);
            attrtdp =
                (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0);
            write_casn_time(&attrtdp->signingTime.utcTime, time((time_t *) 0));
        }

        // we are all done with the content
        free(tbsp);

        // now sign the attributes

        // get the size of signed attributes and allocate space for them
        if ((tbs_lth = size_casn(&sigInfop->signedAttrs.self)) < 0)
        {
            msg = "sizing SignerInfo";
            break;
        }
        tbsp = (uchar *) calloc(1, tbs_lth);
        encode_casn(&sigInfop->signedAttrs.self, tbsp);
        *tbsp = ASN_SET;

        // create a new, fresh hash context for hashing the attrs, and hash
        // them
        CALL(cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2),
             "creating hash context");
        CALL(cryptEncrypt(hashContext, tbsp, tbs_lth), "hashing attrs");
        CALL(cryptEncrypt(hashContext, tbsp, 0), "hashing attrs");

        // get the hash value
        CALL(cryptGetAttributeString
             (hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &signatureLength),
             "getting attr hash");

        // get the key and sign it
        CALL(cryptKeysetOpen
             (&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyfilename,
              CRYPT_KEYOPT_READONLY), "opening key set");
        CALL(cryptCreateContext(&sigKeyContext, CRYPT_UNUSED, CRYPT_ALGO_RSA),
             "creating RSA context");
        sigKeyContext_initialized = true;
        CALL(cryptGetPrivateKey
             (cryptKeyset, &sigKeyContext, CRYPT_KEYID_NAME, "label",
              "password"), "getting key");
        CALL(cryptCreateSignature
             (NULL, 0, &signatureLength, sigKeyContext, hashContext),
             "signing");

        // check the signature to make sure it's right
        signature = (uchar *) calloc(1, signatureLength + 20);

        // second parameter is signatureMaxLength, so we allow a little more
        CALL(cryptCreateSignature
             (signature, signatureLength + 20, &signatureLength, sigKeyContext,
              hashContext), "signing");

        // verify that the signature is right
        CALL(cryptCheckSignature
             (signature, signatureLength, sigKeyContext, hashContext),
             "verifying");

        // end of protected block
    } while (0);

    // done with cryptlib, shut it down
    if (hashContext_initialized)
    {
        cryptDestroyContext(hashContext);
        hashContext_initialized = false;
    }
    if (sigKeyContext_initialized)
    {
        cryptDestroyContext(sigKeyContext);
        sigKeyContext_initialized = false;
    }

    // did we have any trouble above? if so, bail
    if (msg != 0)
    {
        return msg;
    }

    // ok, write the signature back to the object
    struct SignerInfo sigInfo;
    SignerInfo(&sigInfo, (ushort) 0);
    decode_casn(&sigInfo.self, signature);

    // were we supposed to make a bad signature? if so, make it bad
    if (bad)
    {
        uchar *sig;
        int siz = readvsize_casn(&sigInfo.signature, &sig);
        sig[0]++;
        write_casn(&sigInfo.signature, sig, siz);
        free(sig);
    }

    // copy the signature into the object
    copy_casn(&sigInfop->signature, &sigInfo.signature);
    delete_casn(&sigInfo.self);

    // all done with it now
    free(signature);

    // Mark it as encrypted with rsa, no params.
    // See http://www.ietf.org/mail-archive/web/sidr/current/msg04813.html for
    // why we use id_rsadsi_rsaEncryption instead of id_sha_256WithRSAEncryption
    // here.
    write_objid(&sigInfop->signatureAlgorithm.algorithm,
                id_rsadsi_rsaEncryption);
    write_casn(&sigInfop->signatureAlgorithm.parameters.self, (uchar *) "", 0);

    // no errors, we return NULL
    return NULL;
}
Пример #4
0
const char *signCMSBlob(
    struct CMSBlob *cms,
    const char *keyfilename)
{
    bool sigKeyContext_initialized = false;
    CRYPT_CONTEXT sigKeyContext;
    CRYPT_KEYSET cryptKeyset;
    bool hashContext_initialized = false;
    CRYPT_CONTEXT hashContext;
    int tbs_lth;                /* to-be-signed length */
    unsigned char *tbsp = NULL; /* to-be-signed pointer */
    unsigned char *hash[40];    /* stores sha256 message digest */
    int signatureLength;        /* RSA signature length */
    unsigned char *signature = NULL;    /* RSA signature bytes */
    const char *errmsg = NULL;

    struct SignerInfo *signerInfop =
        (struct SignerInfo *)member_casn(&cms->content.signedData.signerInfos.
                                         self, 0);
    struct BlobEncapsulatedContentInfo *encapContentInfop =
        &cms->content.signedData.encapContentInfo;

    if (vsize_casn(&signerInfop->signedAttrs.self) == 0)
    {
        if ((tbs_lth = vsize_casn(&encapContentInfop->eContent)) < 0)
        {
            errmsg = "sizing eContent";
            return errmsg;
        }
        tbsp = (unsigned char *)calloc(1, tbs_lth);
        if (!tbsp)
        {
            errmsg = "out of memory";
            return errmsg;
        }

        tbs_lth = read_casn(&encapContentInfop->eContent, tbsp);
    }
    else
    {
        // get the size of signed attributes and allocate space for them
        if ((tbs_lth = size_casn(&signerInfop->signedAttrs.self)) < 0)
        {
            errmsg = "sizing SignerInfo";
            return errmsg;
        }
        tbsp = (unsigned char *)calloc(1, tbs_lth);
        if (!tbsp)
        {
            errmsg = "out of memory";
            return errmsg;
        }

        // DER-encode signedAttrs
        tbs_lth = encode_casn(&signerInfop->signedAttrs.self, tbsp);
        *tbsp = ASN_SET;        /* replace ASN.1 identifier octet with ASN_SET
                                 * (0x31) */
    }

    // compute SHA-256 of signedAttrs
    if (cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2) < 0 ||
        !(hashContext_initialized = true))
        errmsg = "creating hash context";
    else if (cryptEncrypt(hashContext, tbsp, tbs_lth) < 0 ||
             cryptEncrypt(hashContext, tbsp, 0) < 0)
        errmsg = "hashing attrs";
    else if (cryptGetAttributeString(hashContext, CRYPT_CTXINFO_HASHVALUE,
                                     hash, &signatureLength) < 0)
        errmsg = "getting attr hash";

    // get the key and sign it
    else if (cryptKeysetOpen(&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
                             keyfilename, CRYPT_KEYOPT_READONLY) < 0)
        errmsg = "opening key set";
    else if (cryptCreateContext(&sigKeyContext, CRYPT_UNUSED,
                                CRYPT_ALGO_RSA) < 0 ||
             !(sigKeyContext_initialized = true))
        errmsg = "creating RSA context";
    else if (cryptGetPrivateKey(cryptKeyset, &sigKeyContext, CRYPT_KEYID_NAME,
                                "label", "password") < 0)
        errmsg = "getting key";
    else if (cryptCreateSignature(NULL, 0, &signatureLength, sigKeyContext,
                                  hashContext) < 0)
        errmsg = "signing";

    // compute signature
    else if ((signature =
              (unsigned char *)calloc(1, signatureLength + 20)) == 0)
        errmsg = "out of memory";
    // second parameter is signatureMaxLength, so we allow a little more
    else if (cryptCreateSignature
             (signature, signatureLength + 20, &signatureLength, sigKeyContext,
              hashContext) < 0)
        errmsg = "signing";
    // verify that the signature is right
    else if (cryptCheckSignature(signature, signatureLength, sigKeyContext,
                                 hashContext) < 0)
        errmsg = "verifying";

    if (hashContext_initialized)
    {
        cryptDestroyContext(hashContext);
        hashContext_initialized = false;
    }
    if (sigKeyContext_initialized)
    {
        cryptDestroyContext(sigKeyContext);
        sigKeyContext_initialized = false;
    }

    if (!errmsg)
    {
        struct SignerInfo sigInfo;
        SignerInfo(&sigInfo, (ushort) 0);
        decode_casn(&sigInfo.self, signature);
        // copy the signature into the object
        copy_casn(&signerInfop->signature, &sigInfo.signature);
        delete_casn(&sigInfo.self);
    }

    if (signature)
        free(signature);
    if (tbsp)
        free(tbsp);

    return errmsg;
}
Пример #5
0
int funcion3()
{
	int tam, tam2, tamRelleno, status, keySize, valido, i, tamCert, keyMaxSize;
	long int opcion_l2, opcion_l;
	char opcion[5], *claveEncrypt, *buffer, *ptr, *endptr, *rutaToEncrypt, *directorio, *rutaSim, *nombreSim, *rutaEncrypted, *cabecera1, *cabecera2, *varlocal, *varlocal2, *password, *rutaKeyset, *nombreKeyset, *busSim, *bytesRelleno, *bufferCert, *claveExportada;
	FILE *ptrEncrypt, *ptrSim, *ptrEncrypted, *ptrCert;	
	DIR *dir;
	struct stat st;
	struct dirent *ent;

	CRYPT_CERTIFICATE certificado;
	/*Reservo memoria*/
	nombreKeyset=(char *)malloc(50);
	rutaKeyset=(char *)malloc(120);
	password=(char *)malloc(20);
	rutaToEncrypt=(char *)malloc(120);
	directorio=(char *)malloc(120);
	rutaSim=(char *)malloc(120);
	busSim=(char *)malloc(5);
	nombreSim=(char *)malloc(50);
	rutaEncrypted=(char *)malloc(120);
	varlocal=(char *)malloc(3);
	varlocal2=(char *)malloc(3);
	cabecera1=(char *)malloc(3);
	cabecera2=(char *)malloc(3);
	bytesRelleno=(char *)malloc(2);

	system("clear");
	printf("\n ------------------------------------\n");
	printf("|          Cifrar un archivo          |\n");
	printf(" ------------------------------------\n\n");
	fflush(stdout);
	/*PASO 1. Ruta del archivo a cifrar*/
	do {
		valido=0;
		printf("PASO 1. Introduzca la ruta del archivo que desea cifrar: ");
		scanf("%s", rutaToEncrypt);
		if((ptrEncrypt=fopen(rutaToEncrypt, "rb")) == NULL ) {
			printf("No se encuentra el archivo. Revise la ruta :)\n\n");
			valido=1;
			fflush(stdout);
		} 
	} while(valido==1);

	/*Buscamos el caracter '/' dentro de la cadena. Si está, es porque el usuario metió la ruta completa*/
	if((ptr=(strrchr(rutaToEncrypt, '/')))!=NULL) sprintf(rutaEncrypted, "./Archivos encriptados/%s.enc", ptr+1); //Ruta completa
	else sprintf(rutaEncrypted, "./Archivos encriptados/%s.enc", rutaToEncrypt); //El usuario metió el nombre del archivo

	/*PASO 2. Algoritmo de cifrado*/
	do {
		valido=0;
		printf("\nPASO 2. Seleccione el algoritmo de cifrado que desea utilizar:\n");
		printf("  1. AES (por defecto)\n");
		printf("  2. DES\n");
		printf("  3. RSA\n");
		fflush(stdout);
		printf("Opción (Introduzca 0 para la opción por defecto) >> ");	
	
		scanf ("%s", &opcion);

		/*Comprobacion de la validez de la selección (que sea un número)
		(usando strtol, si hay algun caracter no numérico, endptr apunta al primero de ellos,
		lo cual implica que si la cadena apuntada por endptr no tiene longitud 0
		es porque se ha introducido un caracter no numérico)*/
		opcion_l = strtol(opcion,&endptr,10);

		if(strlen(endptr)!=0 || opcion_l < 0 || opcion_l > 3) {
			printf("Ops... tendrás que meter un número entre 1 y 3 la próxima vez ;) Try again!\n");
			fflush(stdout);
			valido=1;
		}
	} while(valido==1);

	/*Distinto tratamiento según el cifrado escogido*/
	CRYPT_CONTEXT contextoEncrypt, contextoPrivado;
	if(opcion_l==1 || opcion_l==0) { //AES
		/*Vamos a comprobar que tam sea multiplo del tamaño de bloque*/
		stat(rutaToEncrypt, &st);
		tam2=st.st_size;
		if(tam2%16!=0)	{
			tam=(int)tam2/16;
			tam++;
			tam=tam*16;	
			tamRelleno=tam-tam2; 
		}
		else {
			tamRelleno=0;
			tam=tam2;
		}

		/*Creamos contextos..*/
		if((status=cryptCreateContext(&contextoEncrypt, CRYPT_UNUSED, CRYPT_ALGO_AES))!=CRYPT_OK) {
			printf("Error al crear el contexto AES. Código %d\n", status);
			fflush(stdout);
			return(-1);
		} else if((status=cryptSetAttributeString(contextoEncrypt, CRYPT_CTXINFO_IV, "1234567891123456", 16))!=CRYPT_OK) {
			printf("Error con el vector de inicialización. Código %d\n", status);
			fflush(stdout);
			return(-1);
		}
		do { //Seleccionamos el tamaño de clave en AES
			valido=0;
			printf("\nPASO 3. Seleccione el tamaño de clave:\n");
			printf("  1. 128 bits (por defecto)\n");
			printf("  2. 192 bits\n");
			printf("  3. 256 bits\n");
			fflush(stdout);
			printf("Opción (Introduzca 0 para la opción por defecto)>> ");	
			scanf ("%s", &opcion);
			/*Comprobacion de la validez de la selección (que sea un número)
			(usando strtol, si hay algun caracter no numérico, endptr apunta al primero de ellos,
			lo cual implica que si la cadena apuntada por endptr no tiene longitud 0
			es porque se ha introducido un caracter no numérico)*/
			opcion_l2 = strtol(opcion,&endptr,10);
			if(strlen(endptr)!=0 || opcion_l2 < 0 || opcion_l2 > 3) {
				printf("Ops... tendrás que meter un número entre 1 y 3 la próxima vez ;) Try again!\n");
				fflush(stdout);
				valido=1;
			}
		} while(valido==1);
		if(opcion_l2==2) {
			if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_KEYSIZE, 192/8))!=CRYPT_OK) { //192 bits
				printf("Error al asignar tamaño de clave. Código %d\n", status);
				fflush(stdout);
				return(-1);
			}
		} else if(opcion_l2==3) {
			if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_KEYSIZE, 256/8))!=CRYPT_OK) { //256 bits
				printf("Error al asignar tamaño de clave. Código %d\n", status);
				fflush(stdout);
				return(-1);
			}
		}
		strcpy(busSim, ".aes");
		/*Será la cabecera que incluiremos al principio del archivo encriptado*/
		cabecera1=cesarEncrypt("aes", 17, varlocal);/*Ciframos "aes" con cifrado césar. Número de posiciones desplazadas: 17 */
	} else if(opcion_l==2) { //DES
		/*Vamos a comprobar que tam sea multiplo del tamaño de bloque*/
		stat(rutaToEncrypt, &st);
		tam2=st.st_size;
		if(tam2%16!=0)	{
			tam=(int)tam2/16;
			tam++;
			tam=tam*16;	
			tamRelleno=tam-tam2; 
		}
		else {
			tamRelleno=0;
			tam=tam2;
		}

		if((status=cryptCreateContext(&contextoEncrypt, CRYPT_UNUSED, CRYPT_ALGO_DES))!=CRYPT_OK) {
			printf("Error al crear el contexto DES. Código %d\n", status);
			fflush(stdout);
			return(-1);
		} else if((status=cryptSetAttributeString(contextoEncrypt, CRYPT_CTXINFO_IV, "12345678", 8))!=CRYPT_OK) {
			printf("Error con el vector de inicialización. Código %d\n", status);
			fflush(stdout);
			return(-1);
		}
		strcpy(busSim, ".des");

		/*Será la cabecera que incluiremos al principio del ptrEncrypt encriptado*/
		cabecera1=cesarEncrypt("des", 17, varlocal);/*Ciframos "des" con cifrado césar. Número de posiciones desplazadas: 17 */
	} else if(opcion_l==3) { //RSA
		stat(rutaToEncrypt, &st);
		tam2=st.st_size;
		if(tam2%128!=0)	{
			tam=(int)tam2/128;
			tam++;
			tam=tam*128;	 
		}
		else {
			tam=tam2;
		}

	}
	if(opcion_l==0 || opcion_l==1) printf("\nPASO 4. Seleccione el modo de funcionamiento:\n");
	if(opcion_l==2) printf("\nPASO 3. Seleccione el modo de funcionamiento:\n");
	
	/*Modo de funcionamiento si se seleccionó cifrado simétrico*/
	if(opcion_l!=3) {
		do {
			valido=0;
			printf("  1. CBC (por defecto)\n");
			printf("  2. ECB\n");
			fflush(stdout);
			printf("Opción (Introduzca 0 para la opción por defecto) >> ");	
			scanf ("%s", &opcion);
			/*Comprobacion de la validez de la selección (que sea un número)
			(usando strtol, si hay algun caracter no numérico, endptr apunta al primero de ellos,
			lo cual implica que si la cadena apuntada por endptr no tiene longitud 0
			es porque se ha introducido un caracter no numérico)*/
			opcion_l2 = strtol(opcion,&endptr,10);
			if(strlen(endptr)!=0 || opcion_l2 < 0 || opcion_l2 > 2) {
				printf("Ops... tendrás que meter un número entre 1 y 2 la próxima vez ;) Try again!\n");
				fflush(stdout);
				valido=1;
				}
		} while(valido==1);
		if(opcion_l2==1) { //CBC
			if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_MODE, CRYPT_MODE_CBC))!=CRYPT_OK) {
				printf("Error al asignar modo de funcionamiento\n");
				fflush(stdout);
				return(-1);
			}
			cabecera2=cesarEncrypt("cbc", 14, varlocal2); /*Ciframos "cbc" con cifrado césar. Número de posiciones desplazadas: 14 */
		} else if(opcion_l2==2) { //ECB
			if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_MODE, CRYPT_MODE_ECB))!=CRYPT_OK) {
				printf("Error al asignar modo de funcionamiento\n");
				fflush(stdout);
				return(-1);
			}
			cabecera2=cesarEncrypt("ecb", 14, varlocal2); /*Ciframos "ecb" con cifrado césar. Número de posiciones desplazadas: 14 */
		}
		/*Password*/
		if(opcion_l==1 || opcion_l==0) printf("\nPASO 5. Introduzca una contraseña >> "); 	
		if(opcion_l==2)	printf("\nPASO 4. Introduzca una contraseña >> "); 
		fflush(stdout);
	
		do {
			valido=0;
			scanf("%s", password);
			if((strlen(password))<2) {
				printf("La contraseña debe tener más de un caracter\n");
				fflush(stdout);
				valido=1;
			}
				
		}while(valido==1);
	

		/*Necesitamos la clave simétrica adecuada*/
		dir = opendir ("./Claves y certificados/");
		if (dir != NULL) {
			i=0;
			/* Nos va a mostrar los archivos que haya dentro de la carpeta Claves y cert. que correspondan*/
			while ((ent = readdir (dir)) != NULL) {
				if((ptr=strstr(ent->d_name, busSim))!=NULL) { 
					strcpy(nombreSim, ent->d_name);
					i++;
				}
			}
			closedir(dir);
		} else {
			/* Problemas al abrir el directorio */
			printf("¿Ha ejecutado ya la opción 2?\n");
			fflush(stdout);
			return(-1);
		}
		if(i==0) {
			printf("No se ha encontrado ninguna clave simétrica. (¿Ha ejecutado ya la opción 2?)\n");
			fflush(stdout);
			return(-1);
		} else if(i==1) {
			printf("\n-> Se ha encontrado 1 clave simétrica. Se usará %s por defecto\n\n", nombreSim);
			fflush(stdout);
			sprintf(rutaSim, "./Claves y certificados/%s", nombreSim);
		} else {
			printf("\n¡¡ Hay %d claves simétricas creadas !!\n", i);
			fflush(stdout);
			i=0;
			dir = opendir ("./Claves y certificados/");	
			/* Nos va a mostrar los archivos que haya dentro de la carpeta Claves y cert. adecuados*/
			while ((ent = readdir (dir)) != NULL) {
				if((ptr=strstr(ent->d_name, busSim))!=NULL) {
					i++; 
					printf("  %d. %s\n", i, ent->d_name);
				}
			}
			closedir(dir);
		
			do{
				valido=0;
				printf("Introduzca el número de la clave simétrica que desea usar >> ");
				scanf("%s", &opcion);
				opcion_l2 = strtol(opcion,&endptr,10);
				if(strlen(endptr)!=0 || opcion_l2 < 1 || opcion_l2 > i) {
					printf("Ops... tendrás que meter un número entre 1 y %d la próxima vez ;) Try again!\n", i);
					fflush(stdout);
					valido=1;
				}
			}while(valido==1);
	
			/*Guardamos el nombre del archivo correspondiente en rutaSim*/
			dir = opendir ("./Claves y certificados/");
			i=0;
			while ((ent = readdir (dir)) != NULL) {
				if((ptr=strstr(ent->d_name, busSim))!=NULL) {
					i++;
					if(opcion_l2==i) { 
						sprintf(rutaSim, "./Claves y certificados/%s", ent->d_name);
					}	
				}
			}
			closedir(dir);
		}
		/*Recuperamos la clave privada y la guardamos en el contextoPrivado ya que la necesitamos*/
		/*Abrimos el keyset*/
		dir = opendir ("./Claves y certificados/");
		if (dir != NULL) {
			i=0;
			/* Nos va a mostrar los archivos .p15 que haya dentro de la carpeta Claves y cert.*/
			while ((ent = readdir (dir)) != NULL) {
				if((ptr=strstr(ent->d_name, ".p15"))!=NULL) { 
					strcpy(nombreKeyset, ent->d_name);
					i++;
				}
			}
			closedir(dir);
		} else {
			/* Problemas al abrir el directorio */
			printf("¿Ha ejecutado ya la opción 1?\n");
			fflush(stdout);
			return(-1);
		}
	
		if(i==0) {
			printf("\nNo se ha encontrado ningún archivo keyset. (¿Ha ejecutado ya la opción 1?)\n");
			fflush(stdout);
			return(-1);
		} else if(i==1) {
			printf("\n-> Se ha encontrado 1 archivo keyset. Se usará %s por defecto\n\n", nombreKeyset);
			fflush(stdout);
			sprintf(rutaKeyset, "./Claves y certificados/%s", nombreKeyset);
		} else {
			printf("\n¡¡ Hay %d archivos keysets creados !!\n", i);
			i=0;
			dir = opendir ("./Claves y certificados/");	
			/* Nos va a mostrar los archivos .p15 que haya dentro de la carpeta Claves y cert.*/
			while ((ent = readdir (dir)) != NULL) {
				if((ptr=strstr(ent->d_name, ".p15"))!=NULL) {
					i++; 
					printf("  %d. %s\n", i, ent->d_name);
				}
			}
			closedir(dir);
			/*El usuario introduce el número que corresponde al archivo keyset que elija*/
			do{
				valido=0;
				printf("Introduzca el número del archivo keyset que desea usar >> ");
				scanf("%s", &opcion);
				opcion_l2 = strtol(opcion,&endptr,10);
				if(strlen(endptr)!=0 || opcion_l2 < 1 || opcion_l2 > i) {
					printf("Ops... tendrás que meter un número entre 1 y %d la próxima vez ;) Try again!\n", i);
					fflush(stdout);
					valido=1;
				}
			}while(valido==1);
			/*Guardamos el nombre del archivo correspondiente en rutaKeyset*/
			dir = opendir ("./Claves y certificados/");
			i=0;
			while ((ent = readdir (dir)) != NULL) {
				if((ptr=strstr(ent->d_name, ".p15"))!=NULL) {
					i++;
					if(opcion_l2==i) { 
						sprintf(rutaKeyset, "./Claves y certificados/%s", ent->d_name);
					}	
				}
			}
			closedir(dir);
		}
	
		/*Abrimos la clave simétrica elejida anteriormente por el usuario*/
		if((ptrSim=fopen(rutaSim, "rb")) == NULL) {
			printf("Error al abrir la clave simétrica. (¿La ha creado ya?)\n");
			fflush(stdout);
			return(-1);
		}
		stat(rutaSim, &st);
		keySize=st.st_size;
		claveEncrypt=(char *)malloc(keySize);
		status=fread(claveEncrypt, 1, keySize, ptrSim);
	
		/*Abrimos keyset, creamos contextos, importamos claves...*/
		CRYPT_KEYSET keyset;
		if((status=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, rutaKeyset, CRYPT_KEYOPT_READONLY))!=CRYPT_OK) {
			printf("Error al abrir el archivo keyset. (¿Ha ejecutado la opción 1?). Código %d\n", status);
			fflush(stdout);
			return(-1);
		}
		if((status=cryptCreateContext(&contextoPrivado, CRYPT_UNUSED, CRYPT_ALGO_RSA))!=CRYPT_OK) {
			printf("Error al crear el contexto. Código %d\n", status);
			fflush(stdout);
			return(-1);
		}
		if((status=cryptGetPrivateKey(keyset, &contextoPrivado, CRYPT_KEYID_NAME, "claveRSA", password))!=CRYPT_OK) {
			printf("Error con la clave privada. (¿Es la misma contraseña que usó en la opción 1?). Código %d\n", status);
			fflush(stdout);
			return(-1);
		}
		if((status=cryptImportKey(claveEncrypt, keySize, contextoPrivado, contextoEncrypt))!=CRYPT_OK) {
			printf("Error al importar la clave. Asegúrese de que se usa el mismo algoritmo. Código %d\n", status);
			fflush(stdout);
			return(-1);
		}
		/*Encriptamos*/
		buffer=(char *)malloc(tam);
		status=fread(buffer, 1, tam, ptrEncrypt);
		if((status=cryptEncrypt(contextoEncrypt, buffer, tam))!=CRYPT_OK) {
			printf("Error al encriptar %s. Código %d\n", rutaToEncrypt, status);
			fflush(stdout);
			return(-1);
		}
	}

	if(opcion_l==3) {

		if((ptrCert=fopen("./Claves y certificados/AES.cert", "rb")) == NULL ) {
			printf("Compruebe que haya generado ya una clave pública\n");
			fflush(stdout);
			return(-1);
		}
		stat("./Claves y certificados/AES.cert", &st);
		tamCert=st.st_size;
		bufferCert=(char *)malloc(tamCert);
		status=fread(bufferCert, 1, tamCert, ptrCert);

		if((status=cryptImportCert(bufferCert, tamCert, CRYPT_UNUSED, &certificado))!=CRYPT_OK) {
			printf("Error al importar el certificado. Código %d\n", status);
			fflush(stdout);
			return(-1);	
		}

		/*Encriptamos de 128 bytes en 128 bytes. Sin embargo, no podemos hacer cryptEncrypt para el mismo certificado/contexto. Pero lo 
dejamos asi ya que nos dara el error -21 esperado en la primera iteracion*/
		tam2=tam/128;
		buffer=(char *)malloc(tam);
		for(i=0; i<tam2; i++) {
			status=fread(buffer, 1, 128, ptrEncrypt);
			if((status=cryptEncrypt(certificado, buffer, 128))!=CRYPT_OK) {	
				printf("Error al cifrar el archivo %s. Código %d\n", rutaToEncrypt, status);
				fflush(stdout);
				return(-1);
			}
			*ptrEncrypt=*(ptrEncrypt+128);
			*buffer=*(buffer+128);
		}
	}

	/*Guardamos el archivo encriptado.*/
	/*Compruebo que exista el directorio. Si lstat devuelve 0 es que existe. Si devuelve otro valor hay que crear el directorio*/
	sprintf(directorio, "./Archivos encriptados");
	if (status = lstat(directorio, &st) != 0) {
		if(status=mkdir(directorio, 0777) != 0) {
			printf("Error al crear el directorio\n");
			fflush(stdout);
			return(-1);
		}	
	}

	/*La ruta la hemos calculado al principio del todo, cuando el usuario metio la ruta del archivo*/
	if((ptrEncrypted=fopen(rutaEncrypted, "wb")) == NULL) {
		printf("Error al crear el archivo\n");
		fflush(stdout);
		return(-1);
	}
	
	/*Vamos a incluir una cabecera en el archivo para saber después los bytes de relleno que hemos añadido*/
	sprintf(bytesRelleno, "%d", tamRelleno);
	if((status=fwrite(bytesRelleno, 1, 2, ptrEncrypted))!=2) {
		printf("Error al guardar el archivo\n");
		fflush(stdout);
		return(-1);
	}

	/*Vamos a incluir una cabecera en el archivo para saber despues que tipo de cifrado se uso*/
	*(cabecera1+3)='\0'; //Nos aseguramos que solo sean 3 bytes
	if((status=fwrite(cabecera1, 1, strlen(cabecera1), ptrEncrypted))!=strlen(cabecera1)) {
		printf("Error al guardar el archivo\n");
		fflush(stdout);
		return(-1);
	}
	/*Vamos a incluir una cabecera en el archivo para saber después el modo de funcionamiento que se uso*/
	*(cabecera2+3)='\0'; //Nos aseguramos que solo sean 3 bytes
	if((status=fwrite(cabecera2, 1, strlen(cabecera2), ptrEncrypted))!=strlen(cabecera2)) {
		printf("Error al guardar el archivo\n");
		fflush(stdout);
		return(-1);
	}
	/*Guardamos los bytes del archivo encriptado en un archivo*/
	if((status=fwrite(buffer, 1, tam, ptrEncrypted))!=tam) {
		printf("Error al guardar el archivo\n");
		fflush(stdout);
		return(-1);
	}

	/*Cerramos descriptores y destruimos lo que sea necesario*/
	fclose(ptrEncrypted);
	fclose(ptrSim);
	fclose(ptrEncrypt);
	//if((status=cryptKeysetClose(keyset))!=CRYPT_OK) {
	//	printf("Error al cerrar el keyset. Código %d\n", status);
	//	fflush(stdout);
	//	return(-1);
	//}

	if((status=cryptDestroyContext(contextoPrivado))!=CRYPT_OK) {
		printf("Error al destruir el contexto. Código %d\n", status);
		fflush(stdout);
		return(-1);
	}

	if((status=cryptDestroyContext(contextoEncrypt))!=CRYPT_OK) {
		printf("Error al destruir el contexto. Código %d\n", status);
		fflush(stdout);
		return(-1);
	}

	return(0);

}
Пример #6
0
static int exec_cmpcli_revoke(int argc, char **argv) {
  CRYPT_SESSION session;
  CRYPT_CONTEXT privkey;
  CRYPT_KEYSET privkeys;
  CRYPT_CERTIFICATE cert, cacert, revreq;
  const char *cmd, *crtfilename, *cacrtfilename, *kpfilename;
  void *crtdata;
  int status, data_len;

  if (argc != 4) { fprintf(stderr, "cmpcli revoke argv!=4\n"); return 1; }
  cmd = argv[0]; crtfilename=argv[1]; cacrtfilename=argv[2]; kpfilename = argv[3];
  if (strcmp(cmd, "revoke") != 0) { fprintf(stderr, "cmpcli knows revoke only\n"); return 1; }

  crtdata = read_full_file(crtfilename, &data_len);
  if (!crtdata) return 1;
  status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cert);
  WARN_AND_RETURN_IF(status);
  free(crtdata);

  crtdata = read_full_file(cacrtfilename, &data_len);
  if (!crtdata) return 1;
  status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cacert);
  WARN_AND_RETURN_IF(status);
  free(crtdata);

  status = cryptKeysetOpen(&privkeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, kpfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);
  status = cryptGetPrivateKey(privkeys, &privkey, CRYPT_KEYID_NAME, DEFAULT_PRIVKEY_LABEL, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(privkeys);
  WARN_AND_RETURN_IF(status);


  status = cryptCreateCert(&revreq, CRYPT_UNUSED, CRYPT_CERTTYPE_REQUEST_REVOCATION);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CERTIFICATE, cert);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CRLREASON, CRYPT_CRLREASON_AFFILIATIONCHANGED);
  WARN_AND_RETURN_IF(status);
  #if 0
  status = cryptSignCert(revreq, privkey);
  WARN_AND_RETURN_IF(status);
  #endif

  status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_REVOCATION);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_REQUEST, revreq);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_CACERTIFICATE, cacert);
  WARN_AND_RETURN_IF(status);

  #if 0
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_USERNAME, uid, strlen(uid));
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_PASSWORD, rpwd, strlen(rpwd));
  WARN_AND_RETURN_IF(status);
  #endif

  status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1);
  if (!cryptStatusOK(status)) {
    CRYPT_ERRTYPE_TYPE errtype;
    CRYPT_ATTRIBUTE_TYPE locus;
    char *errstring;
    int errstringlen;
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "session errtype %d locus %d\n", errtype, locus);
    cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "revreq errtype %d locus %d\n", errtype, locus);
    cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "cert errtype %d locus %d\n", errtype, locus);
    cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "cacert errtype %d locus %d\n", errtype, locus);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, NULL, &errstringlen);
    errstring = malloc(errstringlen + 10);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, errstring, &errstringlen);
    errstring[errstringlen] = 0;
    fprintf(stderr, "session errmsg: %s\n", errstring);
    free(errstring);
  }
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyContext(privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroySession(session);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(cacert);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(cert);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyCert(revreq);
  WARN_AND_RETURN_IF(status);
  return 0;
}
Пример #7
0
static int exec_cmpsvr(int argc, char **argv) {
  CRYPT_KEYSET cakeys, store;
  CRYPT_SESSION session;
  CRYPT_CONTEXT ca_privkey;
  int status;
  const char *dbfilename = argv[0];
  char cakeysfilename[4096]; /* PATH_MAX */

  if (argc < 1) { fprintf(stderr, "missing dbfilename\n"); return 1; }

  status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP_SERVER);
  WARN_AND_RETURN_IF(status);

  /* open store */
  status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);

  /* get ca privkey */
  snprintf(cakeysfilename, 4095, "%s.keys", dbfilename);
  cakeysfilename[4095] = '\0';
  status = cryptKeysetOpen(&cakeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cakeysfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);
  status = cryptGetPrivateKey(cakeys, &ca_privkey, CRYPT_KEYID_NAME, DEFAULT_CA_PRIVKEY_LABEL, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(cakeys);
  WARN_AND_RETURN_IF(status);

  status = cryptSetAttribute(session, CRYPT_SESSINFO_KEYSET, store);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, ca_privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000);
  WARN_AND_RETURN_IF(status);
  fprintf(stderr, "before setting ACTIVE\n");
  status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1);
  if (!cryptStatusOK(status)) {
    CRYPT_ERRTYPE_TYPE errtype;
    CRYPT_ATTRIBUTE_TYPE locus;
    char *errstring;
    int errstringlen;
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype);
    cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus);
    fprintf(stderr, "session errtype %d locus %d\n", errtype, locus);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, NULL, &errstringlen);
    errstring = malloc(errstringlen + 10);
    cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, errstring, &errstringlen);
    errstring[errstringlen] = 0;
    fprintf(stderr, "session errmsg: %s\n", errstring);
    free(errstring);
  }
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetClose(store);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroyContext(ca_privkey);
  WARN_AND_RETURN_IF(status);
  status = cryptDestroySession(session);
  WARN_AND_RETURN_IF(status);
  return 0;
}
Пример #8
0
static int exec_revoke(int argc, char **argv) {
  const char *id, *dbfilename, *pass;
  char cakeysfilename[4096];
  CRYPT_KEYID_TYPE id_type;
  CRYPT_KEYSET store, cakeys;
  CRYPT_CERTIFICATE cert, crl;
  CRYPT_CONTEXT ca_privkey;
  int status;

  if (argc != 4) {
    fprintf(stderr, "usage: revoke dbfile (-e email | -n name) pass\n");
    return 1;
  }

  dbfilename = argv[0];
  id = argv[2];
  pass = argv[3];
  if (strcmp(argv[1], "-e") == 0) {
    id_type = CRYPT_KEYID_EMAIL;
  }
  else if (strcmp(argv[1], "-n") == 0) {
    id_type = CRYPT_KEYID_NAME;
  }
  else {
    fprintf(stderr, "usage: revoke dbfile (-e email | -n name)\n");
    return 1;
  }

  /* open store */
  status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);

  /* get ca privkey */
  snprintf(cakeysfilename, 4095, "%s.keys", dbfilename);
  status = cryptKeysetOpen(&cakeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cakeysfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);
  status = cryptGetPrivateKey(cakeys, &ca_privkey, CRYPT_KEYID_NAME, DEFAULT_CA_PRIVKEY_LABEL, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(cakeys);
  WARN_AND_RETURN_IF(status);

  /* get cert to revoke */
  status = cryptCAGetItem(store, &cert, CRYPT_CERTTYPE_CERTIFICATE, id_type, id);
  WARN_AND_RETURN_IF(status);

  /* create CRL */
  status = cryptCreateCert(&crl, CRYPT_UNUSED, CRYPT_CERTTYPE_CRL);
  WARN_AND_RETURN_IF(status);
  status = cryptSetAttribute(crl, CRYPT_CERTINFO_CERTIFICATE, cert);
  WARN_AND_RETURN_IF(status);
  status = cryptSignCert(crl, ca_privkey);
  WARN_AND_RETURN_IF(status);

  status = cryptAddPublicKey(store, crl);
  WARN_AND_RETURN_IF(status);


  status = cryptDestroyCert(cert);
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyCert(crl);
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyContext(ca_privkey);
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetClose(store);
  WARN_AND_RETURN_IF(status);
  return 0;
}
Пример #9
0
static int exec_sign(int argc, char **argv) {
  const char *id, *dbfilename, *certfilename;
  char cakeysfilename[4096];
  CRYPT_KEYID_TYPE id_type;
  CRYPT_KEYSET store, cakeys;
  CRYPT_CERTIFICATE cert, csr;
  CRYPT_CONTEXT ca_privkey;
  int status;

  if (argc != 4) {
    fprintf(stderr, "usage: sign dbfile (-e email | -n name) certfile\n");
    return 1;
  }

  dbfilename = argv[0];
  certfilename = argv[3];
  id = argv[2];
  if (strcmp(argv[1], "-e") == 0) {
    id_type = CRYPT_KEYID_EMAIL;
  }
  else if (strcmp(argv[1], "-n") == 0) {
    id_type = CRYPT_KEYID_NAME;
  }
  else {
    fprintf(stderr, "usage: sign dbfile (-e email | -n name) certfile\n");
    return 1;
  }

  status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);

  status = cryptCAGetItem(store, &csr, CRYPT_CERTTYPE_CERTREQUEST, id_type, id);
  WARN_AND_RETURN_IF(status);

  snprintf(cakeysfilename, 4095, "%s.keys", dbfilename);
  status = cryptKeysetOpen(&cakeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cakeysfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);

  status = cryptGetPrivateKey(cakeys, &ca_privkey, CRYPT_KEYID_NAME, DEFAULT_CA_PRIVKEY_LABEL, DEFAULT_PASSWORD);
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetClose(cakeys);
  WARN_AND_RETURN_IF(status);

  status = cryptCACertManagement(&cert, CRYPT_CERTACTION_ISSUE_CERT, store, ca_privkey, csr);
  if (!cryptStatusOK(status)) {
    int errorLocus;
    int errorType;

    cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus);
    cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType);
    fprintf(stderr, "store: locus %d type %d\n", errorLocus, errorType);
    cryptGetAttribute(csr, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus);
    cryptGetAttribute(csr, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType);
    fprintf(stderr, "csr: locus %d type %d\n", errorLocus, errorType);
    cryptGetAttribute(ca_privkey, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus);
    cryptGetAttribute(ca_privkey, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType);
    fprintf(stderr, "ca_privkey: locus %d type %d\n", errorLocus, errorType);
  }
  WARN_AND_RETURN_IF(status);

  status = export_cert(cert, certfilename);
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyCert(cert);
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyCert(csr);
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyContext(ca_privkey);
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetClose(store);
  WARN_AND_RETURN_IF(status);
  return 0;
}