void SecurityKeyManager::createRSA(const dtn::data::EID &ref, const int bits)
		{
			const ibrcommon::File privkey = getKeyFile(ref, SecurityKey::KEY_PRIVATE);
			const ibrcommon::File pubkey = getKeyFile(ref, SecurityKey::KEY_PUBLIC);
			RSA* rsa = RSA_new();
			BIGNUM* e = BN_new();

			BN_set_word(e, 65537);

			RSA_generate_key_ex(rsa, bits, e, NULL);

			BN_free(e);
			e = NULL;

			// write private key
			int fd = ::open(privkey.getPath().c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0600);

			FILE * rsa_privkey_file = fdopen(fd, "w");
			if (!rsa_privkey_file) {
				IBRCOMMON_LOGGER_TAG(SecurityKeyManager::TAG, error) << "Failed to open " << privkey.getPath() << IBRCOMMON_LOGGER_ENDL;
				RSA_free(rsa);
				return;
			}
			PEM_write_RSAPrivateKey(rsa_privkey_file, rsa, NULL, NULL, 0, NULL, NULL);
			fclose(rsa_privkey_file);

			// write public key
			FILE * rsa_pubkey_file = fopen(pubkey.getPath().c_str(), "w+");
			if (!rsa_pubkey_file) {
				IBRCOMMON_LOGGER_TAG(SecurityKeyManager::TAG, error) << "Failed to open " << privkey.getPath() << IBRCOMMON_LOGGER_ENDL;
				RSA_free(rsa);
				return;
			}
			PEM_write_RSA_PUBKEY(rsa_pubkey_file, rsa);
			fclose(rsa_pubkey_file);

			RSA_free(rsa);

			// set trust-level to high
			SecurityKey key = get(ref, SecurityKey::KEY_PUBLIC);
			key.trustlevel = SecurityKey::HIGH;
			store(key);
		}
Example #2
0
int
main (int ac, char **av)
{
	FILE		*f_in;
	FILE		*f_out;
	UINT32		proofLen;
	BYTE		*proof;
	BYTE		*pub;
	UINT32		pubLen;
	BYTE		*certs;
	UINT32		certsLen;
	UINT32		certLen;
	BYTE		key[128/8];
	BYTE		iv[16];
	BYTE		asymPlain[8 + sizeof(key) + SHA_DIGEST_LENGTH];
	unsigned char oaepPad[4] = "TCPA";
	BYTE		*asymPadded;
	UINT32		asymPaddedLength;
	BYTE		*asymEnc;
	UINT32		asymEncLength;
	BYTE		*chal;
	UINT32		chalLen;
	BYTE		*symEnc;
	UINT32		symEncLength;
	BYTE		*symAttest;
	UINT32		symAttestLength;
	EVP_CIPHER_CTX ctx;
	X509		*ekX509;
	X509_NAME	*ekSubj;
	EVP_PKEY	*ekPkey;
	RSA			*ekRsa;
	RSA			*aikRsa;
	UINT32		tt[1];
	int			trousersIVMode = 1;
	int			out1, out2;
	int			nCerts;
	int			result;

	if (ac != 5) {
		fprintf (stderr, "Usage: %s secretfile aikprooffile outchallengefile outrsafile\n", av[0]);
		exit (1);
	}

	/* Read challenge */
	if ((f_in = fopen (av[1], "rb")) == NULL) {
		fprintf (stderr, "Unable to open file %s\n", av[1]);
		exit (1);
	}
	fseek (f_in, 0, SEEK_END);
	chalLen = ftell (f_in);
	fseek (f_in, 0, SEEK_SET);
	chal = malloc (chalLen);
	if (fread (chal, 1, chalLen, f_in) != chalLen) {
		fprintf (stderr, "Unable to read file %s\n", av[1]);
		exit (1);
	}
	fclose (f_in);

	/* Read AIK proof */
	if ((f_in = fopen (av[2], "rb")) == NULL) {
		fprintf (stderr, "Unable to open file %s\n", av[2]);
		exit (1);
	}
	fseek (f_in, 0, SEEK_END);
	proofLen = ftell (f_in);
	fseek (f_in, 0, SEEK_SET);
	proof = malloc (proofLen);
	if (fread (proof, 1, proofLen, f_in) != proofLen) {
		fprintf (stderr, "Unable to read file %s\n", av[2]);
		exit (1);
	}
	fclose (f_in);

	if (proofLen < 3)
		goto badproof;
	pubLen = ntohl (*(UINT32*)proof);
	if (pubLen + 4 + 4 > proofLen)
		goto badproof;
	pub = proof + 4;
	proof += pubLen+4;
	proofLen -= pubLen+4;

	certsLen = ntohl (*(UINT32*)proof);
	if (certsLen + 4 != proofLen)
		goto badproof;
	proof += 4;
	certs = proof;

	nCerts = 0;
	for ( ; ; ) {
		++nCerts;
		if (certsLen < 3)
			goto badproof;
		certLen = (proof[0]<<16) | (proof[1]<<8) | proof[2];
		if (certLen + 3 > certsLen)
			goto badproof;
		proof += certLen + 3;
		certsLen -= certLen + 3;
		if (certsLen == 0)
			break;
	}

	if (verifyCertChain (trustedRoot, sizeof(trustedRoot), nCerts, certs) != 0) {
		fprintf (stderr, "Unable to validate certificate chain in proof file\n");
		exit (1);
	}

	/* Pull endorsement key from 1st cert */
	certLen = (certs[0]<<16) | (certs[1]<<8) | certs[2];
	certs += 3;
	if ((ekX509 = d2i_X509 (NULL, (unsigned char const **)&certs, certLen)) == NULL)
		goto badproof;
	/* One last check: EK certs must have empty subject fields */
	if ((ekSubj = X509_get_subject_name (ekX509)) == NULL)
		goto badproof;
	if (X509_NAME_entry_count (ekSubj) != 0)
		goto badproof;
	/* OpenSSL can't parse EK key due to OAEP OID - fix it */
	{
		X509_PUBKEY *pk = X509_get_X509_PUBKEY(ekX509);
		int algbufLen = i2d_X509_ALGOR(pk->algor, NULL);
		unsigned char *algbuf = malloc(algbufLen);
		unsigned char *algbufPtr = algbuf;
		i2d_X509_ALGOR(pk->algor, &algbufPtr);
		if (algbuf[12] == 7)
			algbuf[12] = 1;
		algbufPtr = algbuf;
		d2i_X509_ALGOR(&pk->algor, (void *)&algbufPtr, algbufLen);
		free (algbuf);
	}
	if ((ekPkey = X509_get_pubkey (ekX509)) == NULL)
		goto badproof;
	if ((ekRsa = EVP_PKEY_get1_RSA (ekPkey)) == NULL)
		goto badproof;

	/* Construct encrypted output challenge */
	RAND_bytes (key, sizeof(key));
	RAND_bytes (iv, sizeof(iv));

	/* Prepare buffer to be RSA encrypted to endorsement key */
	((UINT32 *)asymPlain)[0] = htonl(TPM_ALG_AES);
	((UINT16 *)asymPlain)[2] = htons(TPM_ES_SYM_CBC_PKCS5PAD);
	((UINT16 *)asymPlain)[3] = htons(sizeof(key));
	memcpy (asymPlain+8, key, sizeof(key));
	SHA1 (pub, pubLen, asymPlain + 8 + sizeof(key));

	/* Encrypt to EK */
	/* Must use custom padding for TPM to decrypt it */
	asymPaddedLength = asymEncLength = RSA_size (ekRsa);
	asymPadded = malloc (asymPaddedLength);
	asymEnc = malloc (asymEncLength);
	RSA_padding_add_PKCS1_OAEP(asymPadded, asymPaddedLength, asymPlain,
					sizeof(asymPlain), oaepPad, sizeof(oaepPad));
	RSA_public_encrypt (asymPaddedLength, asymPadded, asymEnc, ekRsa, RSA_NO_PADDING);
	free (asymPadded);
	asymPadded = NULL;

	/* Encrypt challenge with key */
	symEnc = malloc (chalLen + sizeof(iv));
	EVP_CIPHER_CTX_init (&ctx);
	EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv);
	EVP_EncryptUpdate (&ctx, symEnc, &out1, chal, chalLen);
	EVP_EncryptFinal_ex (&ctx, symEnc+out1, &out2);
	EVP_CIPHER_CTX_cleanup(&ctx);
	symEncLength = out1 + out2;

	/* Create TPM_SYM_CA_ATTESTATION struct to hold encrypted cert */
	symAttestLength = 28 + sizeof(iv) + symEncLength;
	symAttest = malloc (symAttestLength);
	((UINT32 *)symAttest)[0] = htonl(symEncLength);
	((UINT32 *)symAttest)[1] = htonl(TPM_ALG_AES);
	((UINT16 *)symAttest)[4] = htons(TPM_ES_SYM_CBC_PKCS5PAD);
	((UINT16 *)symAttest)[5] = htons(TPM_SS_NONE);
	((UINT32 *)symAttest)[3] = htonl(12+sizeof(iv));
	((UINT32 *)symAttest)[4] = htonl(128);		/* Key length in bits */
	((UINT32 *)symAttest)[5] = htonl(sizeof(iv));	/* Block size in bytes */
	((UINT32 *)symAttest)[6] = htonl(sizeof(iv));	/* IV size in bytes */
	memcpy (symAttest+28, iv, sizeof(iv));
	memcpy (symAttest+28+sizeof(iv), symEnc, symEncLength);
	if (trousersIVMode) {
		((UINT32 *)symAttest)[0] = htonl(symEncLength + sizeof(iv));
		((UINT32 *)symAttest)[3] = htonl(12);		/* Take IV to be start of symEnc */
		((UINT32 *)symAttest)[6] = htonl(0);		/* IV size in bytes */
	}
	free (symEnc);
	symEnc = NULL;

	if ((f_out = fopen (av[3], "wb")) == NULL) {
		fprintf (stderr, "Unable to open file %s for output\n", av[3]);
		exit (1);
	}
	/* Precede the two blocks with 4-byte lengths */
	tt[0] = htonl (asymEncLength);
	fwrite (tt, 1, sizeof(UINT32), f_out);
	fwrite (asymEnc, 1, asymEncLength, f_out);
	tt[0] = htonl (symAttestLength);
	fwrite (tt, 1, sizeof(UINT32), f_out);
	if (fwrite (symAttest, 1, symAttestLength, f_out) != symAttestLength) {
		fprintf (stderr, "Unable to write to file %s\n", av[3]);
		exit (1);
	}
	fclose (f_out);

	/* Output RSA key representing the AIK for future use */
	if ((f_out = fopen (av[4], "wb")) == NULL) {
		fprintf (stderr, "Unable to open file %s for output\n", av[4]);
		exit (1);
	}
	aikRsa = RSA_new();
	aikRsa->n = BN_bin2bn (pub+pubLen-256, 256, NULL);
	aikRsa->e = BN_new();
	BN_set_word (aikRsa->e, 0x10001);
	if (PEM_write_RSA_PUBKEY(f_out, aikRsa) < 0) {
		fprintf (stderr, "Unable to write to file %s\n", av[3]);
		exit (1);
	}
	fclose (f_out);

	printf ("Success!\n");
	return 0;

badproof:
	fprintf (stderr, "Input AIK proof file incorrect format\n");
	return 1;
}
Example #3
0
int main(int argc, char** argv) {
    R_RSA_PUBLIC_KEY public_key;
    R_RSA_PRIVATE_KEY private_key;
    int i, n, retval;
    bool is_valid;
    DATA_BLOCK signature, in, out;
    unsigned char signature_buf[256], buf[256], buf2[256];
    FILE *f, *fpriv, *fpub;
    char cbuf[256];
    RSA rsa_key;
    RSA *rsa_key_;
	BIO *bio_out=NULL;
    BIO *bio_err=NULL;
    char *certpath;
    bool b2o=false; // boinc key to openssl key ?
    bool kpriv=false; // private key ?

    if (argc == 1) {
        usage();
        exit(1);
    }
    if (!strcmp(argv[1], "-genkey")) {
        if (argc < 5) {
            usage();
            exit(1);
        }
        printf("creating keys in %s and %s\n", argv[3], argv[4]);
        n = atoi(argv[2]);

        srand(random_int());
        RSA* rp = RSA_generate_key(n,  65537, 0, 0);
        openssl_to_keys(rp, n, private_key, public_key);
        fpriv = fopen(argv[3], "w");
        if (!fpriv) die("fopen");
        fpub = fopen(argv[4], "w");
        if (!fpub) die("fopen");
        print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key));
        print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key));

    } else if (!strcmp(argv[1], "-sign")) {
        if (argc < 4) {
            usage();
            exit(1);
        }
        fpriv = fopen(argv[3], "r");
        if (!fpriv) die("fopen");
        retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key));
        if (retval) die("scan_key_hex\n");
        signature.data = signature_buf;
        signature.len = 256;
        retval = sign_file(argv[2], private_key, signature);
        print_hex_data(stdout, signature);
    } else if (!strcmp(argv[1], "-sign_string")) {
        if (argc < 4) {
            usage();
            exit(1);
        }
        fpriv = fopen(argv[3], "r");
        if (!fpriv) die("fopen");
        retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key));
        if (retval) die("scan_key_hex\n");
        generate_signature(argv[2], cbuf, private_key);
        puts(cbuf);
    } else if (!strcmp(argv[1], "-verify")) {
        if (argc < 5) {
            usage();
            exit(1);
        }
        fpub = fopen(argv[4], "r");
        if (!fpub) die("fopen");
        retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key));
        if (retval) die("read_public_key");
        f = fopen(argv[3], "r");
        signature.data = signature_buf;
        signature.len = 256;
        retval = scan_hex_data(f, signature);
        if (retval) die("scan_hex_data");
        retval = verify_file(argv[2], public_key, signature, is_valid);
        if (retval) die("verify_file");
        if (is_valid) {
            printf("file is valid\n");
        } else {
            printf("file is invalid\n");
            return 1;
        }
    } else if (!strcmp(argv[1], "-test_crypt")) {
        if (argc < 4) {
            usage();
            exit(1);
        }
        fpriv = fopen(argv[2], "r");
        if (!fpriv) die("fopen");
        retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key));
        if (retval) die("scan_key_hex\n");
        fpub = fopen(argv[3], "r");
        if (!fpub) die("fopen");
        retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key));
        if (retval) die("read_public_key");
        strcpy((char*)buf2, "encryption test successful");
        in.data = buf2;
        in.len = strlen((char*)in.data);
        out.data = buf;
        encrypt_private(private_key, in, out);
        in = out;
        out.data = buf2;
        decrypt_public(public_key, in, out);
        printf("out: %s\n", out.data);
    } else if (!strcmp(argv[1], "-cert_verify")) {
        if (argc < 6)
            die("usage: crypt_prog -cert_verify file signature_file certificate_dir ca_dir \n");

        f = fopen(argv[3], "r");
        signature.data = signature_buf;
        signature.len = 256;
        retval = scan_hex_data(f, signature);
        if (retval) die("cannot scan_hex_data");
        certpath = check_validity(argv[4], argv[2], signature.data, argv[5]);
        if (certpath == NULL) {
            die("signature cannot be verfied.\n\n");
        } else {
            printf("siganture verified using certificate '%s'.\n\n", certpath);
            free(certpath);
        }
    // this converts, but an executable signed with sign_executable,
    // and signature converted to OpenSSL format cannot be verified with
    // OpenSSL
    } else if (!strcmp(argv[1], "-convsig")) {
        if (argc < 5) {
            usage();
            exit(1);
        }
        if (strcmp(argv[2], "b2o") == 0) {
            b2o = true;
        } else if (strcmp(argv[2], "o2b") == 0) {
            b2o = false;
        } else {
            die("either 'o2b' or 'b2o' must be defined for -convsig\n");
        }
        if (b2o) {
            f = fopen(argv[3], "r");
            signature.data = signature_buf;
            signature.len = 256;
            retval = scan_hex_data(f, signature);
            fclose(f);
            f = fopen(argv[4], "w+");
            print_raw_data(f, signature);
            fclose(f);
        } else {
            f = fopen(argv[3], "r");
            signature.data = signature_buf;
            signature.len = 256;
            retval = scan_raw_data(f, signature);
            fclose(f);
            f = fopen(argv[4], "w+");
            print_hex_data(f, signature);
            fclose(f);
        }
    } else if (!strcmp(argv[1], "-convkey")) {
        if (argc < 6) {
            usage();
            exit(1);
        }
        if (strcmp(argv[2], "b2o") == 0) {
            b2o = true;
        } else if (strcmp(argv[2], "o2b") == 0) {
            b2o = false;
        } else {
            die("either 'o2b' or 'b2o' must be defined for -convkey\n");
        }
        if (strcmp(argv[3], "pub") == 0) {
            kpriv = false;
        } else if (strcmp(argv[3], "priv") == 0)  {
            kpriv = true;
        } else {
            die("either 'pub' or 'priv' must be defined for -convkey\n");
        }
        OpenSSL_add_all_algorithms();
		ERR_load_crypto_strings();
		ENGINE_load_builtin_engines();
		if (bio_err == NULL) {
		    bio_err = BIO_new_fp(stdout, BIO_NOCLOSE);
        }
        //enc=EVP_get_cipherbyname("des");
        //if (enc == NULL)
        //    die("could not get cypher.\n");
        // no encription yet.
        bio_out=BIO_new(BIO_s_file());
		if (BIO_write_filename(bio_out,argv[5]) <= 0) {
			perror(argv[5]);
            die("could not create output file.\n");
        }
        if (b2o) {
            rsa_key_ = RSA_new();
            if (kpriv) {
                fpriv = fopen(argv[4], "r");
                if (!fpriv) {
                    die("fopen");
                }
                scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key));
                fclose(fpriv);
                private_to_openssl(private_key, &rsa_key);

                //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key,
        		//				enc, NULL, 0, pass_cb, NULL);
        		// no encryption yet.
        		
                //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key,
        		//				NULL, NULL, 0, pass_cb, NULL);
                fpriv = fopen(argv[5], "w+");
                PEM_write_RSAPrivateKey(fpriv, &rsa_key, NULL, NULL, 0, 0, NULL);
                fclose(fpriv);
    		    //if (i == 0) {
                //    ERR_print_errors(bio_err);
                //    die("could not write key file.\n");
    		    //}
            } else {
                fpub = fopen(argv[4], "r");
                if (!fpub) {
                    die("fopen");
                }
                scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key));
                fclose(fpub);
                fpub = fopen(argv[5], "w+");
                if (!fpub) {
                    die("fopen");
                }
                public_to_openssl(public_key, rsa_key_);
    		    i = PEM_write_RSA_PUBKEY(fpub, rsa_key_);
    		    if (i == 0) {
                    ERR_print_errors(bio_err);
                    die("could not write key file.\n");
    		    }
                fclose(fpub);
            }
        } else {
            // o2b
            rsa_key_ = (RSA *)calloc(1, sizeof(RSA));
            memset(rsa_key_, 0, sizeof(RSA));
            if (rsa_key_ == NULL) {
                die("could not allocate memory for RSA structure.\n");
            }
            if (kpriv) {
                fpriv = fopen (argv[4], "r");
                rsa_key_ = PEM_read_RSAPrivateKey(fpriv, NULL, NULL, NULL);
                fclose(fpriv);
                if (rsa_key_ == NULL) {
                    ERR_print_errors(bio_err);
                    die("could not load private key.\n");
                }
                openssl_to_private(rsa_key_, &private_key);
                fpriv = fopen(argv[5], "w");
                if (!fpriv) {
                    die("fopen");
                }
                print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key));
            } else {
                fpub = fopen (argv[4], "r");
                rsa_key_ = PEM_read_RSA_PUBKEY(fpub, NULL, NULL, NULL);
                fclose(fpub);
                if (rsa_key_ == NULL) {
                    ERR_print_errors(bio_err);
                    die("could not load public key.\n");
                }
                openssl_to_keys(rsa_key_, 1024, private_key, public_key);
                //openssl_to_public(rsa_key_, &public_key);
                public_to_openssl(public_key, rsa_key_); //
                fpub = fopen(argv[5], "w");
                if (!fpub) {
                    die("fopen");
                }
                print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key));
            }
        }
    } else {
        usage();
        exit(1);
    }
    return 0;
}
Example #4
0
		inline void rsa_key::write_certificate_public_key(file _file) const
		{
			error::throw_error_if_not(PEM_write_RSA_PUBKEY(_file.raw(), ptr().get()) != 0);
		}