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); }
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; }
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; }
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); }