int main(void) { EVP_CIPHER_CTX *ctx = NULL; unsigned char key[16]; unsigned char iv[12]; unsigned char tag[16]; unsigned char data[128]; unsigned char ori_msg[128]; unsigned char enc_msg[128+16]; unsigned char dec_msg[128]; int r, len, enc_msg_len, dec_msg_len; const EVP_CIPHER* cipher = NULL; ERR_load_CRYPTO_strings(); OPENSSL_add_all_algorithms_noconf(); r = RAND_bytes(key, sizeof(key)); assert(r == 1); r = RAND_bytes(iv, sizeof(iv)); assert(r == 1); r = RAND_pseudo_bytes(data, sizeof(data)); assert(r == 1); r = RAND_pseudo_bytes(ori_msg, sizeof(ori_msg)); assert(r == 1); r = RAND_pseudo_bytes(enc_msg, sizeof(enc_msg)); assert(r == 1); cipher = EVP_aes_128_gcm(); ctx = EVP_CIPHER_CTX_new(); assert(ctx); EVP_CIPHER_CTX_init(ctx); len = EVP_CIPHER_key_length(cipher); assert(len == sizeof(key)); len = EVP_CIPHER_iv_length(cipher); assert(len == sizeof(iv)); r = EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv); assert(r == 1); r = EVP_EncryptUpdate(ctx, NULL, &enc_msg_len, data, sizeof(data)); assert(r == 1); r = EVP_EncryptUpdate(ctx, enc_msg, &enc_msg_len, ori_msg, sizeof(ori_msg)); assert(r == 1); assert(enc_msg_len == sizeof(ori_msg)); r = EVP_EncryptFinal_ex(ctx, enc_msg + enc_msg_len, &len); assert(r == 1); assert(len == 0); r = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof(tag), tag); assert(r == 1); r = EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv); assert(r == 1); r = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof(tag), tag); assert(r == 1); r = EVP_DecryptUpdate(ctx, NULL, &dec_msg_len, data, sizeof(data)); assert(r == 1); r = EVP_DecryptUpdate(ctx, dec_msg, &dec_msg_len, enc_msg, enc_msg_len); assert(r == 1); assert(dec_msg_len == enc_msg_len); r = EVP_DecryptFinal_ex(ctx, dec_msg + dec_msg_len, &len); assert(r == 1); assert(len == 0); assert(memcmp(ori_msg, dec_msg, dec_msg_len) == 0); EVP_CIPHER_CTX_free(ctx); puts("OK!"); return 0; }
int main(int argc, char *argv[]) { BN_CTX *ctx; BIO *out = NULL; int i, ret; unsigned char c; BIGNUM *r_mont, *r_mont_const, *r_recp, *r_simple, *a, *b, *m; RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we * don't even check its return * value (which we should) */ ERR_load_BN_strings(); ctx = BN_CTX_new(); if (ctx == NULL) EXIT(1); r_mont = BN_new(); r_mont_const = BN_new(); r_recp = BN_new(); r_simple = BN_new(); a = BN_new(); b = BN_new(); m = BN_new(); if ((r_mont == NULL) || (r_recp == NULL) || (a == NULL) || (b == NULL)) goto err; out = BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out, stdout, BIO_NOCLOSE); for (i = 0; i < 200; i++) { RAND_bytes(&c, 1); c = (c % BN_BITS) - BN_BITS2; BN_rand(a, NUM_BITS + c, 0, 0); RAND_bytes(&c, 1); c = (c % BN_BITS) - BN_BITS2; BN_rand(b, NUM_BITS + c, 0, 0); RAND_bytes(&c, 1); c = (c % BN_BITS) - BN_BITS2; BN_rand(m, NUM_BITS + c, 0, 1); BN_mod(a, a, m, ctx); BN_mod(b, b, m, ctx); ret = BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL); if (ret <= 0) { printf("BN_mod_exp_mont() problems\n"); ERR_print_errors(out); EXIT(1); } ret = BN_mod_exp_recp(r_recp, a, b, m, ctx); if (ret <= 0) { printf("BN_mod_exp_recp() problems\n"); ERR_print_errors(out); EXIT(1); } ret = BN_mod_exp_simple(r_simple, a, b, m, ctx); if (ret <= 0) { printf("BN_mod_exp_simple() problems\n"); ERR_print_errors(out); EXIT(1); } ret = BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL); if (ret <= 0) { printf("BN_mod_exp_mont_consttime() problems\n"); ERR_print_errors(out); EXIT(1); } if (BN_cmp(r_simple, r_mont) == 0 && BN_cmp(r_simple, r_recp) == 0 && BN_cmp(r_simple, r_mont_const) == 0) { printf("."); fflush(stdout); } else { if (BN_cmp(r_simple, r_mont) != 0) printf("\nsimple and mont results differ\n"); if (BN_cmp(r_simple, r_mont_const) != 0) printf("\nsimple and mont const time results differ\n"); if (BN_cmp(r_simple, r_recp) != 0) printf("\nsimple and recp results differ\n"); printf("a (%3d) = ", BN_num_bits(a)); BN_print(out, a); printf("\nb (%3d) = ", BN_num_bits(b)); BN_print(out, b); printf("\nm (%3d) = ", BN_num_bits(m)); BN_print(out, m); printf("\nsimple ="); BN_print(out, r_simple); printf("\nrecp ="); BN_print(out, r_recp); printf("\nmont ="); BN_print(out, r_mont); printf("\nmont_ct ="); BN_print(out, r_mont_const); printf("\n"); EXIT(1); } } BN_free(r_mont); BN_free(r_mont_const); BN_free(r_recp); BN_free(r_simple); BN_free(a); BN_free(b); BN_free(m); BN_CTX_free(ctx); ERR_remove_thread_state(NULL); CRYPTO_mem_leaks(out); BIO_free(out); printf("\n"); if (test_exp_mod_zero() != 0) goto err; printf("done\n"); EXIT(0); err: ERR_load_crypto_strings(); ERR_print_errors(out); #ifdef OPENSSL_SYS_NETWARE printf("ERROR\n"); #endif EXIT(1); return (1); }
SESSION *session_init_client (void) { SESSION *session; if ((session = (SESSION *) calloc (1, sizeof (SESSION))) == NULL) return NULL; session->client_OS = 0x00; /* 0x00 == Windows, 0x01 == Mac OS X */ memcpy(session->client_id, "\x01\x04\x01\x01", 4); session->client_revision = 99999; /* * Client and server generate 16 random bytes each. */ RAND_bytes (session->client_random_16, 16); if ((session->rsa = RSA_generate_key (1024, 65537, NULL, NULL)) == NULL) { DSFYDEBUG ("RSA key generation failed with error %lu\n", ERR_get_error ()); } assert (session->rsa != NULL); /* * Create a private and public key. * This, along with key signing, is used to securely * agree on a session key for the Shannon stream cipher. * */ session->dh = DH_new (); session->dh->p = BN_bin2bn (DH_prime, 96, NULL); session->dh->g = BN_bin2bn (DH_generator, 1, NULL); assert (DH_generate_key (session->dh) == 1); BN_bn2bin (session->dh->priv_key, session->my_priv_key); BN_bn2bin (session->dh->pub_key, session->my_pub_key); /* * Found in Storage.dat (cache) at offset 16. * Automatically generated, but we're lazy. * */ memcpy (session->cache_hash, "\xf4\xc2\xaa\x05\xe8\x25\xa7\xb5\xe4\xe6\x59\x0f\x3d\xd0\xbe\x0a\xef\x20\x51\x95", 20); session->cache_hash[0] = (unsigned char) getpid (); session->ap_sock = -1; session->username[0] = 0; session->server_host[0] = 0; session->server_port = 0; session->key_recv_IV = 0; session->key_send_IV = 0; session->user_info.username[0] = 0; session->user_info.country[0] = 0; session->user_info.server_host[0] = 0; session->user_info.server_port = 0; return session; }
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, const unsigned char *salt, int saltlen, unsigned char *aiv, uint64_t N, uint64_t r, uint64_t p) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid; size_t keylen = 0; EVP_CIPHER_CTX *ctx = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; PBE2PARAM *pbe2 = NULL; ASN1_OBJECT *obj; if (!cipher) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER); goto err; } if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ASN1_R_INVALID_SCRYPT_PARAMETERS); goto err; } alg_nid = EVP_CIPHER_type(cipher); if (alg_nid == NID_undef) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); goto err; } obj = OBJ_nid2obj(alg_nid); pbe2 = PBE2PARAM_new(); if (pbe2 == NULL) goto merr; /* Setup the AlgorithmIdentifier for the encryption scheme */ scheme = pbe2->encryption; scheme->algorithm = obj; scheme->parameter = ASN1_TYPE_new(); if (scheme->parameter == NULL) goto merr; /* Create random IV */ if (EVP_CIPHER_iv_length(cipher)) { if (aiv) memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) goto err; } ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) goto merr; /* Dummy cipherinit to just setup the IV */ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0) goto err; if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) < 0) { ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; /* If its RC2 then we'd better setup the key length */ if (alg_nid == NID_rc2_cbc) keylen = EVP_CIPHER_key_length(cipher); /* Setup keyfunc */ X509_ALGOR_free(pbe2->keyfunc); pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p); if (pbe2->keyfunc == NULL) goto merr; /* Now set up top level AlgorithmIdentifier */ ret = X509_ALGOR_new(); if (ret == NULL) goto merr; ret->algorithm = OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2, &ret->parameter) == NULL) goto merr; PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; merr: ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); X509_ALGOR_free(kalg); X509_ALGOR_free(ret); EVP_CIPHER_CTX_free(ctx); return NULL; }
static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key, unsigned char *out, const unsigned char *inp, size_t inp_len, int n4x) /* n4x is 1 or 2 */ { HASH_DESC hash_d[8], edges[8]; CIPH_DESC ciph_d[8]; unsigned char storage[sizeof(SHA1_MB_CTX)+32]; union { u64 q[16]; u32 d[32]; u8 c[128]; } blocks[8]; SHA1_MB_CTX *ctx; unsigned int frag, last, packlen, i, x4=4*n4x; size_t ret = 0; u8 *IVs; ctx = (SHA1_MB_CTX *)(storage+32-((size_t)storage%32)); /* align */ frag = (unsigned int)inp_len>>(1+n4x); last = (unsigned int)inp_len+frag-(frag<<(1+n4x)); if (last>frag && ((last+13+9)%64)<(x4-1)) { frag++; last -= x4-1; } hash_d[0].ptr = inp; for (i=1;i<x4;i++) hash_d[i].ptr = hash_d[i-1].ptr+frag; for (i=0;i<x4;i++) { unsigned int len = (i==(x4-1)?last:frag); ctx->A[i] = key->md.h0; ctx->B[i] = key->md.h1; ctx->C[i] = key->md.h2; ctx->D[i] = key->md.h3; ctx->E[i] = key->md.h4; /* fix seqnum */ #if defined(BSWAP8) blocks[i].q[0] = BSWAP8(BSWAP8(*(u64*)key->md.data)+i); #else blocks[i].c[7] += ((u8*)key->md.data)[7]+i; if (blocks[i].c[7] < i) { int j; for (j=6;j>=0;j--) { if (blocks[i].c[j]=((u8*)key->md.data)[j]+1) break; } } #endif blocks[i].c[8] = ((u8*)key->md.data)[8]; blocks[i].c[9] = ((u8*)key->md.data)[9]; blocks[i].c[10] = ((u8*)key->md.data)[10]; /* fix length */ blocks[i].c[11] = (u8)(len>>8); blocks[i].c[12] = (u8)(len); memcpy(blocks[i].c+13,hash_d[i].ptr,64-13); hash_d[i].ptr += 64-13; hash_d[i].blocks = (len-(64-13))/64; edges[i].ptr = blocks[i].c; edges[i].blocks = 1; } /* hash 13-byte headers and first 64-13 bytes of inputs */ sha1_multi_block(ctx,edges,n4x); /* hash bulk inputs */ sha1_multi_block(ctx,hash_d,n4x); memset(blocks,0,sizeof(blocks)); for (i=0;i<x4;i++) { unsigned int len = (i==(x4-1)?last:frag), off = hash_d[i].blocks*64; const unsigned char *ptr = hash_d[i].ptr+off; off = len-(64-13)-off; /* remainder actually */ memcpy(blocks[i].c,ptr,off); blocks[i].c[off]=0x80; len += 64+13; /* 64 is HMAC header */ len *= 8; /* convert to bits */ if (off<(64-8)) { blocks[i].d[15] = BSWAP4(len); edges[i].blocks = 1; } else { blocks[i].d[31] = BSWAP4(len); edges[i].blocks = 2; } edges[i].ptr = blocks[i].c; } /* hash input tails and finalize */ sha1_multi_block(ctx,edges,n4x); memset(blocks,0,sizeof(blocks)); for (i=0;i<x4;i++) { blocks[i].d[0] = BSWAP4(ctx->A[i]); ctx->A[i] = key->tail.h0; blocks[i].d[1] = BSWAP4(ctx->B[i]); ctx->B[i] = key->tail.h1; blocks[i].d[2] = BSWAP4(ctx->C[i]); ctx->C[i] = key->tail.h2; blocks[i].d[3] = BSWAP4(ctx->D[i]); ctx->D[i] = key->tail.h3; blocks[i].d[4] = BSWAP4(ctx->E[i]); ctx->E[i] = key->tail.h4; blocks[i].c[20] = 0x80; blocks[i].d[15] = BSWAP4((64+20)*8); edges[i].ptr = blocks[i].c; edges[i].blocks = 1; } /* finalize MACs */ sha1_multi_block(ctx,edges,n4x); packlen = 5+16+((frag+20+16)&-16); out += (packlen<<(1+n4x))-packlen; inp += (frag<<(1+n4x))-frag; RAND_bytes((IVs=blocks[0].c),16*x4); /* ask for IVs in bulk */ for (i=x4-1;;i--) { unsigned int len = (i==(x4-1)?last:frag), pad, j; unsigned char *out0 = out; out += 5+16; /* place for header and explicit IV */ ciph_d[i].inp = out; ciph_d[i].out = out; memmove(out,inp,len); out += len; /* write MAC */ ((u32 *)out)[0] = BSWAP4(ctx->A[i]); ((u32 *)out)[1] = BSWAP4(ctx->B[i]); ((u32 *)out)[2] = BSWAP4(ctx->C[i]); ((u32 *)out)[3] = BSWAP4(ctx->D[i]); ((u32 *)out)[4] = BSWAP4(ctx->E[i]); out += 20; len += 20; /* pad */ pad = 15-len%16; for (j=0;j<=pad;j++) *(out++) = pad; len += pad+1; ciph_d[i].blocks = len/16; len += 16; /* account for explicit iv */ /* arrange header */ out0[0] = ((u8*)key->md.data)[8]; out0[1] = ((u8*)key->md.data)[9]; out0[2] = ((u8*)key->md.data)[10]; out0[3] = (u8)(len>>8); out0[4] = (u8)(len); /* explicit iv */ memcpy(ciph_d[i].iv, IVs, 16); memcpy(&out0[5], IVs, 16); ret += len+5; if (i==0) break; out = out0-packlen; inp -= frag; IVs += 16; } aesni_multi_cbc_encrypt(ciph_d,&key->ks,n4x); OPENSSL_cleanse(blocks,sizeof(blocks)); OPENSSL_cleanse(ctx,sizeof(*ctx)); return ret; }
int main(int argc, char *argv[]) { int c, poll = 0, reqversion = 0, rc = -1; char *cacertfile = NULL, *keyfile = NULL, *challenge = NULL, *savedrequestfile = NULL, *requestfile = NULL, *dn = NULL, *spkacfile = NULL, *endrequest = NULL; scep_t scep; BIO *repbio; char *url = "http://localhost/cgi-bin"; scepmsg_t *msg; unsigned char *checkNonce = NULL; /* initialize what you can */ scepinit(); scep_clear(&scep); /* we are a client */ scep.client = 1; /* parse command line */ while (EOF != (c = getopt(argc, argv, "dc:e:r:s:k:w:pu:2a:q:"))) switch (c) { case 'd': debug++; break; case 'e': endrequest = optarg; break; case 'c': cacertfile = optarg; break; case 's': savedrequestfile = optarg; case 'r': /* the request file will also contain the self */ /* signed certificate */ requestfile = optarg; break; case 'k': keyfile = optarg; break; case 'w': challenge = optarg; break; case 'p': poll = 1; break; case 'q': scep.community = optarg; break; case 'u': url = optarg; break; case '2': reqversion = 1; break; case 'a': spkacfile = optarg; break; } /* stop immediately if request or key is missing */ /* (even in the case of a version 2 proxied request, we need */ /* a request as the carrier of the proxy entities public key) */ if (keyfile == NULL) { BIO_printf(bio_err, "%s:%d: key file is required argument\n", __FILE__, __LINE__); goto err; } if (requestfile == NULL) { BIO_printf(bio_err, "%s:%d: request file is required " "argument\n", __FILE__, __LINE__); goto err; } /* we are preparing the request message */ msg = &scep.request; /* decode the URL */ if (parseurl(&scep, url) < 0) { BIO_printf(bio_err, "%s:%d: cannot parse url\n", __FILE__, __LINE__); goto err; } if (debug) BIO_printf(bio_err, "%s:%d: decoded URL %s|%d|%s\n", __FILE__, __LINE__, scep.h.httphost, scep.h.httpport, scep.h.httppath); /* read the client key and request information */ if (read_clientstuff(&scep, requestfile, keyfile) < 0) { BIO_printf(bio_err, "%s:%d: failed to read client stuff\n", __FILE__, __LINE__); goto err; } /* now we have to decide about the payload we want to have */ /* with our scep request: */ /* - for a version 1 request, this will always be the original */ /* certificate signing request */ /* - for a version 2 request, it will be a payload structure */ switch (reqversion) { case 0: /* for a version 1 client, client pubkey and client req */ /* coincide */ scep.requestorpubkey = scep.clientpubkey; scep.requestorreq = scep.clientreq; if (debug) BIO_printf(bio_err, "%s:%d: end request coincides " "with SCEP client\n", __FILE__, __LINE__); break; case 1: msg->rd.payload = payload_new(); rc = -1; if (spkacfile) { if (debug) BIO_printf(bio_err, "%s:%d: reading spki " "from %s\n", __FILE__, __LINE__, spkacfile); rc = read_requestorstuff(&scep, 1, spkacfile); } else if (endrequest) { if (debug) BIO_printf(bio_err, "%s:%d: reading X509 req " "from %s\n", __FILE__, __LINE__, endrequest); rc = read_requestorstuff(&scep, 0, endrequest); } if (rc < 0) { BIO_printf(bio_err, "%s:%d: could not read end " "request data\n", __FILE__, __LINE__); goto err; } if (debug) BIO_printf(bio_err, "%s:%d: end request read\n", __FILE__, __LINE__); break; } /* set the transaction id value */ scep.transId = key_fingerprint(scep.requestorpubkey); if (debug) BIO_printf(bio_err, "%s:%d: transaction ID is %s\n", __FILE__, __LINE__, scep.transId); /* read the CA certificate file */ if (read_castuff(&scep, cacertfile) < 0) { BIO_printf(bio_err, "%s:%d: read CA certificate info\n", __FILE__, __LINE__); } if (debug) BIO_printf(bio_err, "%s:%d: CA certificate read\n", __FILE__, __LINE__); /* for SPKI requests, there should be exactly one more argument */ /* namely the distinguished name */ if (spkacfile) { if ((argc - optind) != 1) { BIO_printf(bio_err, "%s:%d: DN argument needed\n", __FILE__, __LINE__); goto err; } dn = argv[optind]; if (debug) BIO_printf(bio_err, "%s:%d: DN argument is '%s'\n", __FILE__, __LINE__, dn); /* convert the DN into attributes and add them to the */ /* payload */ if (payload_dn_to_attrs(msg->rd.payload, dn) < 0) { BIO_printf(bio_err, "%s:%d: failed to add DN attrs\n", __FILE__, __LINE__); goto err; } } /* skip creation of a request message when polling */ if (poll) goto pollinginit; /* pack the request as a PKSCReq message, of type PKCSReq */ switch (reqversion) { case 0: msg->messageType = SCEP_MESSAGE_TYPE_PKCSREQ; msg->rd.req = scep.clientreq; break; case 1: /* build a version 2 payload */ if (debug) BIO_printf(bio_err, "%s:%d: building version 2 " "payload\n", __FILE__, __LINE__); if (scep.requestorreq) payload_set_req(msg->rd.payload, scep.requestorreq); if (scep.requestorspki) payload_set_spki(msg->rd.payload, scep.requestorspki); /* set the correct message type */ if (scep.community) { /* compute the authenticator from the original */ /* request and the community */ msg->messageType = SCEP_MESSAGE_TYPE_V2PROXY; } else { msg->messageType = SCEP_MESSAGE_TYPE_V2REQUEST; } break; } /* write the request to the request file, for later perusal */ if (savedrequestfile) { BIO *reqbio; reqbio = BIO_new(BIO_s_file()); BIO_write_filename(reqbio, savedrequestfile); switch (reqversion) { case 0: /* version 1 request has a X509_REQ payload */ PEM_write_bio_X509_REQ(reqbio, msg->rd.req); break; case 1: /* version 2 requests have a "real" payload */ i2d_payload_bio(reqbio, msg->rd.payload); break; } BIO_free(reqbio); } goto common; pollinginit: /* when polling, the request is a GetCertInitial message */ msg->messageType = SCEP_MESSAGE_TYPE_GETCERTINITIAL; /* the contents is the pair issuer and subject */ msg->rd.is = (issuer_and_subject_t *)malloc( sizeof(issuer_and_subject_t)); msg->rd.is->issuer = X509_get_subject_name(scep.cacert); msg->rd.is->subject = NULL; /* when polling we should read the request from request file */ /* (only needed for the distinguished name of the client) */ if (debug) BIO_printf(bio_err, "%s:%d: getting subject X509_NAME\n", __FILE__, __LINE__); switch (reqversion) { case 0: msg->rd.is->subject = X509_REQ_get_subject_name(scep.clientreq); break; case 1: if (scep.requestorreq) msg->rd.is->subject = X509_REQ_get_subject_name(scep.requestorreq); if (scep.requestorspki) { if (debug) BIO_printf(bio_err, "%s:%d: converting DN '%s' " "to X509_NAME\n", __FILE__, __LINE__, dn); msg->rd.is->subject = ldap_to_x509(dn); } break; } if (msg->rd.is->subject == NULL) { BIO_printf(bio_err, "%s:%d: no subject found\n", __FILE__, __LINE__); goto err; } if (debug) BIO_printf(bio_err, "%s:%d: issuer and subject found\n", __FILE__, __LINE__); common: /* create a self signed certificate for use with SCEP */ if (selfsigned(&scep) < 0) { BIO_printf(bio_err, "%s:%d: failed to create self signed " "certificate\n", __FILE__, __LINE__); goto err; } if (debug) BIO_printf(bio_err, "%s:%d: self signed certificate created\n", __FILE__, __LINE__); /* set the senderNonce */ scep.senderNonceLength = 16; scep.senderNonce = (unsigned char *)malloc(scep.senderNonceLength); RAND_bytes(scep.senderNonce, scep.senderNonceLength); if (debug) BIO_printf(bio_err, "%s:%d: senderNonce set\n", __FILE__, __LINE__); checkNonce = scep.senderNonce; /* all messages sent from the client are base 64 encoded */ msg->base64 = 1; /* encode */ if (encode(&scep) < 0) { BIO_printf(bio_err, "%s:%d: encoding the request failed\n", __FILE__, __LINE__); goto err; } if (debug) BIO_printf(bio_err, "%s:%d: encoded bytes: %d\n", __FILE__, __LINE__, scep.request.length); /* send the request to the server, read the reply */ repbio = getrequest(&scep); if (repbio == NULL) { BIO_printf(bio_err, "%s:%d: failed to read correct reply\n", __FILE__, __LINE__); goto err; } /* analyze the reply */ if (decode(&scep, repbio) < 0) { BIO_printf(bio_err, "%s:%d: decoding the reply failed\n", __FILE__, __LINE__); goto err; } /* display some information about the reply */ printf("transaction id: %s\n", scep.transId); printf("PKIstatus: %s\n", (scep.reply.pkiStatus) ? scep.reply.pkiStatus : "(null)"); printf("reply message type: %s\n", scep.reply.messageType); if (scep.reply.failinfo) { printf("failinfo: %s\n", scep.reply.failinfo); } /* make sure we get a CertRep message back */ if (strcmp(scep.reply.messageType, SCEP_MESSAGE_TYPE_CERTREP)) { BIO_printf(bio_err, "%s:%d: only CertRep message acceptable " " in response to PKCSReq/GetCertInitial\n", __FILE__, __LINE__); goto err; } /* check for the Nonces */ if (memcmp(checkNonce, scep.recipientNonce, 16)) { BIO_printf(bio_err, "%s:%d: recipientNonce != sent " "senderNonce\n", __FILE__, __LINE__); goto err; } if (debug) BIO_printf(bio_err, "%s:%d: Nonce check OK\n", __FILE__, __LINE__); if (scep.reply.pkiStatus == NULL) { BIO_printf(bio_err, "no pkiStatus returned\n"); exit(1); } switch (atoi(scep.reply.pkiStatus)) { case PKI_SUCCESS: /* Success */ scep.clientcert = extract_cert(&scep); if (debug) BIO_printf(bio_err, "%s:%d: certificate returned %p\n", __FILE__, __LINE__, scep.clientcert); if (scep.clientcert) { BIO *cb; cb = BIO_new(BIO_s_file()); BIO_set_fp(cb, stdout, BIO_NOCLOSE); PEM_write_bio_X509(cb, scep.clientcert); BIO_free(cb); } exit(EXIT_SUCCESS); break; case PKI_FAILURE: /* Failure */ if (debug) BIO_printf(bio_err, "%s:%d: request failed: %s\n", __FILE__, __LINE__, scep.reply.failinfo); exit(1); break; case PKI_PENDING: /* Pending */ if (debug) BIO_printf(bio_err, "%s:%d: request still pending\n", __FILE__, __LINE__); exit(2); break; } /* error return */ err: ERR_print_errors(bio_err); exit(EXIT_FAILURE); }
int RAND_write_file(const char *file) { unsigned char buf[BUFSIZE]; int i,ret=0,rand_err=0; FILE *out = NULL; int n; #if defined(O_CREAT) && !defined(WIN32) /* For some reason Win32 can't write to files created this way */ /* chmod(..., 0600) is too late to protect the file, * permissions should be restrictive from the start */ int fd = open(file, O_CREAT, 0600); if (fd != -1) out = fdopen(fd, "wb"); #endif if (out == NULL) out = fopen(file,"wb"); if (out == NULL) goto err; #ifndef NO_CHMOD chmod(file,0600); #endif n=RAND_DATA; for (;;) { i=(n > BUFSIZE)?BUFSIZE:n; n-=BUFSIZE; if (RAND_bytes(buf,i) <= 0) rand_err=1; i=fwrite(buf,1,i,out); if (i <= 0) { ret=0; break; } ret+=i; if (n <= 0) break; } #ifdef VMS /* Try to delete older versions of the file, until there aren't any */ { char *tmpf; tmpf = OPENSSL_malloc(strlen(file) + 4); /* to add ";-1" and a nul */ if (tmpf) { strcpy(tmpf, file); strcat(tmpf, ";-1"); while(delete(tmpf) == 0) ; rename(file,";1"); /* Make sure it's version 1, or we will reach the limit (32767) at some point... */ } } #endif /* VMS */ fclose(out); memset(buf,0,BUFSIZE); err: return (rand_err ? -1 : ret); }
void LLSecAPIBasicHandler::_writeProtectedData() { std::ostringstream formatted_data_ostream; U8 salt[STORE_SALT_SIZE]; U8 buffer[BUFFER_READ_SIZE]; U8 encrypted_buffer[BUFFER_READ_SIZE]; if(mProtectedDataMap.isUndefined()) { LLFile::remove(mProtectedDataFilename); return; } // create a string with the formatted data. LLSDSerialize::toXML(mProtectedDataMap, formatted_data_ostream); std::istringstream formatted_data_istream(formatted_data_ostream.str()); // generate the seed RAND_bytes(salt, STORE_SALT_SIZE); // write to a temp file so we don't clobber the initial file if there is // an error. std::string tmp_filename = mProtectedDataFilename + ".tmp"; llofstream protected_data_stream(tmp_filename.c_str(), llofstream::binary); try { EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit(&ctx, EVP_rc4(), salt, NULL); unsigned char unique_id[MAC_ADDRESS_BYTES]; LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); LLXORCipher cipher(unique_id, sizeof(unique_id)); cipher.encrypt(salt, STORE_SALT_SIZE); protected_data_stream.write((const char *)salt, STORE_SALT_SIZE); while (formatted_data_istream.good()) { formatted_data_istream.read((char *)buffer, BUFFER_READ_SIZE); if(formatted_data_istream.gcount() == 0) { break; } int encrypted_length; EVP_EncryptUpdate(&ctx, encrypted_buffer, &encrypted_length, buffer, formatted_data_istream.gcount()); protected_data_stream.write((const char *)encrypted_buffer, encrypted_length); } // no EVP_EncrypteFinal, as this is a stream cipher EVP_CIPHER_CTX_cleanup(&ctx); protected_data_stream.close(); } catch (...) { // it's good practice to clean up any secure information on error // (even though this file isn't really secure. Perhaps in the future // it may be, however. LLFile::remove(tmp_filename); throw LLProtectedDataException("Error writing Protected Data Store"); } // move the temporary file to the specified file location. if((((LLFile::isfile(mProtectedDataFilename) != 0) && (LLFile::remove(mProtectedDataFilename) != 0))) || (LLFile::rename(tmp_filename, mProtectedDataFilename))) { LLFile::remove(tmp_filename); throw LLProtectedDataException("Could not overwrite protected data store"); } }
int neverbleed_init(neverbleed_t *nb, char *errbuf) { int pipe_fds[2] = {-1, -1}, listen_fd = -1; char *tempdir = NULL; const RSA_METHOD *default_method = RSA_PKCS1_SSLeay(); rsa_method.rsa_pub_enc = default_method->rsa_pub_enc; rsa_method.rsa_pub_dec = default_method->rsa_pub_dec; rsa_method.rsa_verify = default_method->rsa_verify; /* setup the daemon */ if (pipe(pipe_fds) != 0) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "pipe(2) failed:%s", strerror(errno)); goto Fail; } fcntl(pipe_fds[1], F_SETFD, O_CLOEXEC); if ((tempdir = strdup("/tmp/openssl-privsep.XXXXXX")) == NULL) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "no memory"); goto Fail; } if (mkdtemp(tempdir) == NULL) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to create temporary directory under /tmp:%s", strerror(errno)); goto Fail; } memset(&nb->sun_, 0, sizeof(nb->sun_)); nb->sun_.sun_family = AF_UNIX; snprintf(nb->sun_.sun_path, sizeof(nb->sun_.sun_path), "%s/_", tempdir); RAND_bytes(nb->auth_token, sizeof(nb->auth_token)); if ((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "socket(2) failed:%s", strerror(errno)); goto Fail; } if (bind(listen_fd, (void *)&nb->sun_, sizeof(nb->sun_)) != 0) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to bind to %s:%s", nb->sun_.sun_path, strerror(errno)); goto Fail; } if (listen(listen_fd, SOMAXCONN) != 0) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "listen(2) failed:%s", strerror(errno)); goto Fail; } switch (fork()) { case -1: snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "fork(2) failed:%s", strerror(errno)); goto Fail; case 0: close(pipe_fds[1]); #ifdef __linux__ prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); #endif memcpy(daemon_auth_token, nb->auth_token, NEVERBLEED_AUTH_TOKEN_SIZE); daemon_main(listen_fd, pipe_fds[0], tempdir); break; default: break; } close(listen_fd); listen_fd = -1; close(pipe_fds[0]); pipe_fds[0] = -1; /* setup engine */ if ((nb->engine = ENGINE_new()) == NULL || !ENGINE_set_id(nb->engine, "neverbleed") || !ENGINE_set_name(nb->engine, "privilege separation software engine") || !ENGINE_set_RSA(nb->engine, &rsa_method)) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to initialize the OpenSSL engine"); goto Fail; } ENGINE_add(nb->engine); /* setup thread key */ pthread_key_create(&nb->thread_key, dispose_thread_data); free(tempdir); return 0; Fail: if (pipe_fds[0] != -1) close(pipe_fds[0]); if (pipe_fds[1] != -1) close(pipe_fds[1]); if (tempdir != NULL) { unlink_dir(tempdir); free(tempdir); } if (listen_fd != -1) close(listen_fd); if (nb->engine != NULL) { ENGINE_free(nb->engine); nb->engine = NULL; } return -1; }
static void parse_options(struct ts *ts, int argc, char **argv) { int j, i, ca_err = 0, server_err = 1, input_addr_err = 0, output_addr_err = 0, ident_err = 0, port_set = 0; while ((j = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { if (j == '?') exit(EXIT_FAILURE); switch (j) { case 'i': // -- ident ts->ident = optarg; break; case 'd': // --daemon ts->pidfile = optarg; break; case 'N': // --notify-program ts->notify_program = optarg; break; case 'S': // --syslog ts->syslog_active = 1; ts->syslog_remote = 0; break; case 'l': // --syslog-host ts->syslog_host = optarg; ts->syslog_active = 1; ts->syslog_remote = 1; break; case 'L': // --syslog-port ts->syslog_port = atoi(optarg); break; case 'F': // --log-file log_filename = optarg; break; case 'I': // --input input_addr_err = !parse_io_param(&ts->input, optarg, O_RDONLY, 0); break; case '1': // --input-source if (!inet_aton(optarg, &ts->input.isrc)) { fprintf(stderr, "ERROR: Can't parse input-source IP address: %s\n", optarg); exit(EXIT_FAILURE); } break; case 'R': // --input-rtp ts->rtp_input = !ts->rtp_input; break; case 'z': // --input-ignore-disc ts->ts_discont = !ts->ts_discont; break; case 'M': // --input-service ts->forced_service_id = strtoul(optarg, NULL, 0) & 0xffff; break; case 'T': // --input-buffer ts->input_buffer_time = strtoul(optarg, NULL, 0); break; case 'W': // --input-dump ts->input_dump_filename = optarg; break; case 'O': // --output output_addr_err = !parse_io_param(&ts->output, optarg, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); break; case 'o': // --output-intf if (strchr(optarg, '.')) inet_aton(optarg, &ts->output.intf); else ts->output.v6_if_index = atoi(optarg); break; case 't': // --output-ttl ts->output.ttl = atoi(optarg); break; case 'r': // --output-rtp ts->rtp_output = 1; break; case 'k': // --output-rtp-ssrc ts->rtp_ssrc = strtoul(optarg, NULL, 0); break; case 'g': // --output-tos ts->output.tos = (uint8_t)strtol(optarg, NULL, 0); break; case 'u': // --no-output-on-error ts->no_output_on_error = !ts->no_output_on_error; break; case 'p': // --no-output-filter ts->pid_filter = !ts->pid_filter; break; case 'y': // --output-nit-pass ts->nit_passthrough = !ts->nit_passthrough; break; case 'w': // --output-eit-pass ts->eit_passthrough = !ts->eit_passthrough; break; case 'x': // --output-tdt-pass ts->tdt_passthrough = !ts->tdt_passthrough; break; case 'c': // --ca-system if (strcasecmp("IRDETO", optarg) == 0) ts->req_CA_sys = CA_IRDETO; else if (strcasecmp("CONNAX", optarg) == 0 || strcasecmp("CONAX", optarg) == 0) ts->req_CA_sys = CA_CONAX; else if (strcasecmp("CRYPTOWORKS", optarg) == 0) ts->req_CA_sys = CA_CRYPTOWORKS; else if (strcasecmp("SECA", optarg) == 0 || strcasecmp("MEDIAGUARD", optarg) == 0) ts->req_CA_sys = CA_SECA; else if (strcasecmp("VIACCESS", optarg) == 0) ts->req_CA_sys = CA_VIACCESS; else if (strcasecmp("VIDEOGUARD", optarg) == 0 || strcasecmp("NDS", optarg) == 0) ts->req_CA_sys = CA_VIDEOGUARD; else if (strcasecmp("NAGRA", optarg) == 0) ts->req_CA_sys = CA_NAGRA; else if (strcasecmp("DRE-CRYPT", optarg) == 0 || strcasecmp("DRECRYPT", optarg) == 0) ts->req_CA_sys = CA_DRECRYPT; else if (strcasecmp("BULCRYPT", optarg) == 0) ts->req_CA_sys = CA_BULCRYPT; else if (strcasecmp("GRIFFIN", optarg) == 0) ts->req_CA_sys = CA_GRIFFIN; else if (strcasecmp("DGCRYPT", optarg) == 0) ts->req_CA_sys = CA_DGCRYPT; else ca_err = 1; break; case 'C': // --caid ts->forced_caid = strtoul(optarg, NULL, 0) & 0xffff; break; case 'Y': // --const-cw ts->camd.constant_codeword = 1; if (strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x') optarg += 2; if (strlen(optarg) != CODEWORD_LENGTH * 2) { fprintf(stderr, "ERROR: Constant code word should be %u characters long.\n", CODEWORD_LENGTH * 2); exit(EXIT_FAILURE); } if (decode_hex_string(optarg, ts->camd.key->cw, strlen(optarg)) < 0) { fprintf(stderr, "ERROR: Invalid hex string for constant code word: %s\n", optarg); exit(EXIT_FAILURE); } camd_set_cw(ts, ts->camd.key->cw, 0); ts->camd.key->is_valid_cw = 1; break; case 'Q': // --biss-key ts->camd.constant_codeword = 1; if (strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x') optarg += 2; uint8_t *key = ts->camd.key->cw; // Sometimes the BISS keys are entered with their checksums already calculated (16 symbols, 8 bytes) // This is the same as constant cw with the same key for even and odd if (strlen(optarg) == (BISSKEY_LENGTH + 2) * 2) { if (decode_hex_string(optarg, key, strlen(optarg)) < 0) { fprintf(stderr, "ERROR: Invalid hex string for BISS key: %s\n", optarg); exit(EXIT_FAILURE); } } else { // BISS key without checksum (12 symbols, 6 bytes) if (strlen(optarg) != BISSKEY_LENGTH * 2) { fprintf(stderr, "ERROR: BISS key should be %u characters long.\n", BISSKEY_LENGTH * 2); exit(EXIT_FAILURE); } if (decode_hex_string(optarg, key, strlen(optarg)) < 0) { fprintf(stderr, "ERROR: Invalid hex string for BISS key: %s\n", optarg); exit(EXIT_FAILURE); } // Calculate BISS KEY crc memmove(key + 4, key + 3, 3); key[3] = (uint8_t)(key[0] + key[1] + key[2]); key[7] = (uint8_t)(key[4] + key[5] + key[6]); } // Even and odd keys are the same memcpy(key + 8, key, 8); camd_set_cw(ts, ts->camd.key->cw, 0); ts->camd.key->is_valid_cw = 1; break; case 'A': // --camd-proto if (strcasecmp(optarg, "cs378x") == 0) { camd_proto_cs378x(&ts->camd.ops); } else if (strcasecmp(optarg, "newcamd") == 0) { camd_proto_newcamd(&ts->camd.ops); } else { fprintf(stderr, "Unknown CAMD protocol: %s\n", optarg); exit(EXIT_FAILURE); } break; case 's': // --camd-server server_err = !parse_host_and_port(optarg, &ts->camd.hostname, &ts->camd.service, &port_set); break; case 'U': // --camd-user if (strlen(optarg) < 64) ts->camd.user = optarg; break; case 'P': // --camd-pass ts->camd.pass = optarg; break; case 'B': // --camd-des-key if (strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x') optarg += 2; if (strlen(optarg) != DESKEY_LENGTH) { fprintf(stderr, "ERROR: des key should be %u characters long.\n", DESKEY_LENGTH); exit(EXIT_FAILURE); } strncpy(ts->camd.newcamd.hex_des_key, optarg, sizeof(ts->camd.newcamd.hex_des_key) - 1); ts->camd.newcamd.hex_des_key[sizeof(ts->camd.newcamd.hex_des_key) - 1] = 0; break; case '4': // --ipv4 ai_family = AF_INET; break; case '6': // --ipv6 ai_family = AF_INET6; break; case 'e': // --emm ts->process_emm = !ts->process_emm; break; case 'Z': // --emm-pid ts->forced_emm_pid = strtoul(optarg, NULL, 0) & 0x1fff; break; case 'E': // --emm-only ts->process_emm = 1; ts->process_ecm = 0; ts->output_stream = 0; break; case 'f': // --emm-report-time ts->emm_report_interval = strtoul(optarg, NULL, 10); if (ts->emm_report_interval > 86400) ts->emm_report_interval = 86400; break; case 'a': // --emm-filter if (ts->emm_filters_num + 1 > MAX_FILTERS) { fprintf(stderr, "ERROR: Maximum allowed filters are %d.\n", MAX_FILTERS); exit(EXIT_FAILURE); } if (filter_parse(optarg, &ts->emm_filters[ts->emm_filters_num])) { ts->emm_filters_num++; } else { fprintf(stderr, "ERROR: Can't parse EMM filter: %s\n", optarg); exit(EXIT_FAILURE); } break; case 'X': // --ecm-pid ts->forced_ecm_pid = strtoul(optarg, NULL, 0) & 0x1fff; break; case 'v': // --ecm-only ts->process_emm = 0; ts->process_ecm = 1; ts->output_stream = 0; break; case 'H': // --ecm-report-time ts->ecm_report_interval = strtoul(optarg, NULL, 10); if (ts->ecm_report_interval > 86400) ts->ecm_report_interval = 86400; break; case 'G': // --ecm-irdeto-type ts->irdeto_ecm_idx = strtoul(optarg, NULL, 0); ts->irdeto_ecm_filter_type = IRDETO_FILTER_IDX; break; case '2': // --ecm-irdeto-chid ts->irdeto_ecm_chid = strtoul(optarg, NULL, 0); ts->irdeto_ecm_filter_type = IRDETO_FILTER_CHID; break; case 'K': // --ecm-no-log ts->ecm_cw_log = !ts->ecm_cw_log; break; case 'J': // --cw-warn-time ts->cw_warn_sec = strtoul(optarg, NULL, 10); if (ts->cw_warn_sec > 86400) ts->cw_warn_sec = 86400; ts->cw_last_warn= ts->cw_last_warn + ts->cw_warn_sec; break; case 'q': // --ecm-and-emm-only ts->process_emm = 1; ts->process_ecm = 1; ts->output_stream = 0; break; case 'D': // --debug ts->debug_level = atoi(optarg); if (ts->debug_level > 0) ts->pid_report = 1; break; case 'j': // --pid-report ts->pid_report = 1; break; case 'b': // --bench csa_benchmark(); exit(EXIT_SUCCESS); case 'n': // --ecm-file case 'm': // --emm-file packet_from_file = 1; packet_buflen = file_hex2buf(optarg, packet_buf, sizeof(packet_buf)); if (!packet_buflen) { fprintf(stderr, "ERROR: Can't init packet from file.\n"); exit(1); } packet_type = j == 'n' ? ECM_MSG : EMM_MSG; break; case 'h': // --help show_help(ts); exit(EXIT_SUCCESS); case 'V': // --version printf("%s\n", program_id); exit(EXIT_SUCCESS); } } if (!ts->ident) { if (ts->syslog_active || ts->notify_program) ident_err = 1; } if (packet_from_file) { int err = 0; if (!ts->forced_caid) { fprintf(stderr, "ERROR: CAID was not set. Use --caid option.\n"); err++; } if (!ts->forced_service_id) { fprintf(stderr, "ERROR: Service id was not set. Use --input-service option.\n"); err++; } if (err) exit(EXIT_FAILURE); ts->threaded = 0; input_addr_err = 0; output_addr_err = 0; ts->input.type = FILE_IO; ts->input.fd = 0; ts->output.type = FILE_IO; ts->output.fd = 1; ts->pid_filter = 0; ts->process_ecm = 0; ts->process_emm = 0; ts->output_stream = 0; ts->camd.no_reconnect = 1; ts->camd.check_emm_errors = 1; ts->emm_filters_num = 0; } // Constant codeword is special. Disable conflicting options if (ts->camd.constant_codeword) { server_err = 0; // No server settings are required ts->process_ecm = 0; ts->process_emm = 0; ts->output_stream = 1; } if (ident_err || ca_err || server_err || input_addr_err || output_addr_err || ts->input.type == WTF_IO || ts->output.type == WTF_IO) { show_help(ts); if (ident_err) fprintf(stderr, "ERROR: Ident is not set, please use --ident option.\n"); if (ca_err) fprintf(stderr, "ERROR: Requested CA system is unsupported.\n"); if (server_err) fprintf(stderr, "ERROR: CAMD server address is not set or it is invalid.\n"); if (input_addr_err) fprintf(stderr, "ERROR: Input address is invalid.\n"); if (output_addr_err) fprintf(stderr, "ERROR: Output address is invalid.\n"); exit(EXIT_FAILURE); } if (decode_hex_string(ts->camd.newcamd.hex_des_key, ts->camd.newcamd.bin_des_key, DESKEY_LENGTH) < 0) { fprintf(stderr, "ERROR: Invalid hex string for des key: %s\n", ts->camd.newcamd.hex_des_key); exit(EXIT_FAILURE); } if (ts->camd.ops.proto == CAMD_NEWCAMD && !port_set) { fprintf(stderr, "ERROR: CAMD server port is not set. Use --camd-server %s:xxxx to set the port.\n", ts->camd.hostname); exit(EXIT_FAILURE); } if (log_filename) { log_file = fopen(log_filename, "a"); if (!log_file) { fprintf(stderr, "ERROR: Can't open log file %s: %s\n", log_filename, strerror(errno)); exit(EXIT_FAILURE); } } if (ts->ident) ts_LOGf("Ident : %s\n", ts->ident); if (ts->notify_program) ts_LOGf("Notify prg : %s\n", ts->notify_program); if (ts->pidfile) ts_LOGf("Daemonize : %s pid file.\n", ts->pidfile); if (ts->syslog_active) { if (ts->syslog_remote) ts_LOGf("Syslog : %s:%d\n", ts->syslog_host, ts->syslog_port); else ts_LOGf("Syslog : enabled\n"); } else { if (!packet_from_file) ts_LOGf("Syslog : disabled\n"); } if (!ts->camd.constant_codeword) { if (ts->forced_caid) ts->req_CA_sys = ts_get_CA_sys(ts->forced_caid); if (!ts->forced_caid) ts_LOGf("CA System : %s\n", ts_get_CA_sys_txt(ts->req_CA_sys)); else ts_LOGf("CA System : %s | CAID: 0x%04x (%d)\n", ts_get_CA_sys_txt(ts->req_CA_sys), ts->forced_caid, ts->forced_caid); } else { char cw_even[64], cw_odd[64]; ts_hex_dump_buf(cw_even, sizeof(cw_even), ts->key.cw , 8, 0); ts_hex_dump_buf(cw_odd , sizeof(cw_odd ), ts->key.cw + 8, 8, 0); ts_LOGf("Constant CW: even = %s\n", cw_even); ts_LOGf("Constant CW: odd = %s\n", cw_odd); } if (ts->input.type == NET_IO) { ts_LOGf("Input addr : %s://%s:%s/\n", ts->rtp_input ? "rtp" : "udp", ts->input.hostname, ts->input.service); ts_LOGf("Input src : %s\n", inet_ntoa(ts->input.isrc)); if (ts->input_buffer_time) { ts_LOGf("Input buff : %u ms\n", ts->input_buffer_time); } } else if (ts->input.type == FILE_IO) { if (!packet_from_file) ts_LOGf("Input file : %s\n", ts->input.fd == 0 ? "STDIN" : ts->input.fname); } if (ts->input_dump_filename) { ts->input_dump_file = fopen(ts->input_dump_filename, "w"); if (ts->input_dump_file) ts_LOGf("Input dump : %s\n", ts->input_dump_filename); else ts_LOGf("Input dump : %s | ERROR: %s\n", ts->input_dump_filename, strerror(errno)); } if (ts->forced_service_id) ts_LOGf("Service id : 0x%04x (%d)\n", ts->forced_service_id, ts->forced_service_id); if (ts->req_CA_sys == CA_IRDETO) { switch (ts->irdeto_ecm_filter_type) { case IRDETO_FILTER_IDX : ts_LOGf("Irdeto ECM : Index: 0x%02x (%d)\n", ts->irdeto_ecm_idx, ts->irdeto_ecm_idx); break; case IRDETO_FILTER_CHID: ts_LOGf("Irdeto ECM : CHID: 0x%04x (%d)\n", ts->irdeto_ecm_chid, ts->irdeto_ecm_chid); break; } } if (ts->output_stream) { if (ts->output.type == NET_IO) { ts_LOGf("Output addr: %s://%s:%s/\n", ts->rtp_output ? "rtp" : "udp", ts->output.hostname, ts->output.service); ts_LOGf("Output intf: %s (IPv6 intf index:%d)\n", inet_ntoa(ts->output.intf), ts->output.v6_if_index); ts_LOGf("Output ttl : %d\n", ts->output.ttl); if (ts->output.tos > -1) ts_LOGf("Output TOS : %u (0x%02x)\n", ts->output.tos, ts->output.tos); if (ts->rtp_output) { ts_LOGf("RTP SSRC : %u (0x%04x)\n", ts->rtp_ssrc, ts->rtp_ssrc); // It is recommended that RTP seqnum starts with random number RAND_bytes((unsigned char *)&(ts->rtp_seqnum), 2); } } else if (ts->output.type == FILE_IO) { ts_LOGf("Output file: %s\n", ts->output.fd == 1 ? "STDOUT" : ts->output.fname); } ts_LOGf("Out filter : %s (%s)%s\n", ts->pid_filter ? "enabled" : "disabled", ts->pid_filter ? "output only service related PIDs" : "output everything", ts->no_output_on_error ? " (No output on CW error)" : "" ); if (ts->pid_filter) { if (ts->nit_passthrough) ts_LOGf("Out filter : Pass through NIT.\n"); if (ts->eit_passthrough) ts_LOGf("Out filter : Pass through EIT (EPG).\n"); if (ts->tdt_passthrough) ts_LOGf("Out filter : Pass through TDT/TOT.\n"); } ts_LOGf("TS discont : %s\n", ts->ts_discont ? "report" : "ignore"); ts->threaded = !(ts->input.type == FILE_IO && ts->input.fd != 0); ts_LOGf("Decoding : %s\n", ts->threaded ? "threaded" : "single thread"); } else { ts_LOGf("Decoding : disabled\n"); } if (!ts->camd.constant_codeword) { ts_LOGf("CAMD proto : %s\n", ts->camd.ops.ident); ts_LOGf("CAMD addr : %s:%s%s\n", ts->camd.hostname, ts->camd.service, ai_family == AF_INET ? " (IPv4 only)" : ai_family == AF_INET6 ? " (IPv6 only)" : " (IPv4/IPv6)" ); ts_LOGf("CAMD user : %s\n", ts->camd.user); ts_LOGf("CAMD pass : %s\n", ts->camd.pass); if (ts->camd.ops.proto == CAMD_NEWCAMD) ts_LOGf("CAMD deskey: %s\n", ts->camd.newcamd.hex_des_key); } if (!packet_from_file) ts_LOGf("EMM process: %s\n", ts->process_emm ? "Yes" : "No"); if (ts->process_emm) { if (ts->forced_emm_pid) ts_LOGf("EMM pid : 0x%04x (%d)\n", ts->forced_emm_pid, ts->forced_emm_pid); if (ts->emm_report_interval) ts_LOGf("EMM report : %d sec\n", ts->emm_report_interval); else ts_LOGf("EMM report : disabled\n"); for (i = 0; i < ts->emm_filters_num; i++) { char tmp[512]; filter_dump(&ts->emm_filters[i], tmp, sizeof(tmp)); ts_LOGf("EMM filter : [%2d] %s\n", i + 1, tmp); } } if (!packet_from_file) ts_LOGf("ECM process: %s\n", ts->process_ecm ? "Yes" : "No"); if (ts->process_ecm) { if (ts->forced_ecm_pid) ts_LOGf("ECM pid : 0x%04x (%d)\n", ts->forced_ecm_pid, ts->forced_ecm_pid); if (ts->ecm_report_interval) ts_LOGf("ECM report : %d sec\n", ts->emm_report_interval); else ts_LOGf("ECM report : disabled\n"); if (ts->cw_warn_sec) ts_LOGf("CW warning : %d sec\n", ts->cw_warn_sec); else ts_LOGf("CW warning : disabled\n"); if (!ts->ecm_cw_log) ts_LOGf("ECM/CW log : disabled\n"); } if (ts->ident) { int len = strlen(ts->ident); for (i = 0; i < len; i++) { if (ts->ident[i] == '/') ts->ident[i] = '-'; } } }
static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) { unsigned char *buf=NULL; int ret=0,bit,bytes,mask; time_t tim; if (bits == 0) { BN_zero(rnd); return 1; } bytes=(bits+7)/8; bit=(bits-1)%8; mask=0xff<<(bit+1); buf=(unsigned char *)OPENSSL_malloc(bytes); if (buf == NULL) { BNerr(BN_F_BNRAND,ERR_R_MALLOC_FAILURE); goto err; } /* make a random number and set the top and bottom bits */ time(&tim); RAND_add(&tim,sizeof(tim),0.0); if (pseudorand) { if (RAND_pseudo_bytes(buf, bytes) == -1) goto err; } else { if (RAND_bytes(buf, bytes) <= 0) goto err; } #if 1 if (pseudorand == 2) { /* generate patterns that are more likely to trigger BN library bugs */ int i; unsigned char c; for (i = 0; i < bytes; i++) { RAND_pseudo_bytes(&c, 1); if (c >= 128 && i > 0) buf[i] = buf[i-1]; else if (c < 42) buf[i] = 0; else if (c < 84) buf[i] = 255; } } #endif if (top != -1) { if (top) { if (bit == 0) { buf[0]=1; buf[1]|=0x80; } else { buf[0]|=(3<<(bit-1)); } } else { buf[0]|=(1<<bit); } } buf[0] &= ~mask; if (bottom) /* set bottom bit if requested */ buf[bytes-1]|=1; if (!BN_bin2bn(buf,bytes,rnd)) goto err; ret=1; err: if (buf != NULL) { OPENSSL_cleanse(buf,bytes); OPENSSL_free(buf); } bn_check_top(rnd); return(ret); }
void HC_DEPRECATED DES_generate_random_block(DES_cblock *block) { RAND_bytes(block, sizeof(*block)); }
void HC_DEPRECATED DES_rand_data(void *outdata, int size) { RAND_bytes(outdata, size); }
int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, const unsigned char *mHash, const EVP_MD *Hash, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; unsigned char *H, *salt = NULL, *p; EVP_MD_CTX ctx; hLen = EVP_MD_size(Hash); /* * Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is maximized * -N reserved */ if (sLen == -1) sLen = hLen; else if (sLen == -2) sLen = -2; else if (sLen < -2) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = RSA_size(rsa); if (MSBits == 0) { *EM++ = 0; emLen--; } if (sLen == -2) { sLen = emLen - hLen - 2; } else if (emLen < (hLen + sLen + 2)) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (!salt) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, ERR_R_MALLOC_FAILURE); goto err; } if (!RAND_bytes(salt, sLen)) goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; EVP_MD_CTX_init(&ctx); EVP_DigestInit_ex(&ctx, Hash, NULL); EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes); EVP_DigestUpdate(&ctx, mHash, hLen); if (sLen) EVP_DigestUpdate(&ctx, salt, sLen); EVP_DigestFinal(&ctx, H, NULL); EVP_MD_CTX_cleanup(&ctx); /* Generate dbMask in place then perform XOR on it */ PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash); p = EM; /* Initial PS XORs with all zeroes which is a NOP so just update * pointer. Note from a test above this value is guaranteed to * be non-negative. */ p += emLen - sLen - hLen - 2; *p++ ^= 0x1; if (sLen > 0) { for (i = 0; i < sLen; i++) *p++ ^= salt[i]; } if (MSBits) EM[0] &= 0xFF >> (8 - MSBits); /* H is already in place so just set final 0xbc */ EM[emLen - 1] = 0xbc; ret = 1; err: if (salt) OPENSSL_free(salt); return ret; }
int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) { GOST_KEY_TRANSPORT *gkt=NULL; EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); struct gost_pmeth_data *data = (gost_pmeth_data*)EVP_PKEY_CTX_get_data(pctx); const struct gost_cipher_info *param=get_encryption_params(NULL); unsigned char ukm[8], shared_key[32], crypted_key[44]; int ret=0; int key_is_ephemeral=1; gost_ctx cctx; EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx); if (data->shared_ukm) { TINYCLR_SSL_MEMCPY(ukm, data->shared_ukm,8); } else if (out) { if (RAND_bytes(ukm,8)<=0) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_RANDOM_GENERATOR_FAILURE); return 0; } } /* Check for private key in the peer_key of context */ if (sec_key) { key_is_ephemeral=0; if (!gost_get0_priv_key(sec_key)) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); goto err; } } else { key_is_ephemeral=1; if (out) { sec_key = EVP_PKEY_new(); EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new()); EVP_PKEY_copy_parameters(sec_key,pubk); if (!gost2001_keygen((EC_KEY*)EVP_PKEY_get0(sec_key))) { goto err; } } } if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list) { param= gost_cipher_list+1; } if (out) { VKO_compute_key(shared_key,32,EC_KEY_get0_public_key((const EC_KEY*)EVP_PKEY_get0(pubk)),(EC_KEY*)EVP_PKEY_get0(sec_key),ukm); gost_init(&cctx,param->sblock); keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key); } gkt = GOST_KEY_TRANSPORT_new(); if (!gkt) { goto err; } if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm,8)) { goto err; } if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) { goto err; } if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) { goto err; } if (key_is_ephemeral) { if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk)) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CANNOT_PACK_EPHEMERAL_KEY); goto err; } } ASN1_OBJECT_free(gkt->key_agreement_info->cipher); gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key); if (!key_is_ephemeral) { /* Set control "public key from client certificate used" */ if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); goto err; } } if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1; GOST_KEY_TRANSPORT_free(gkt); return ret; err: if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key); GOST_KEY_TRANSPORT_free(gkt); return -1; }
void TunnelPool::TestTunnels () { for (auto it: m_Tests) { LogPrint (eLogWarning, "Tunnels: test of tunnel ", it.first, " failed"); // if test failed again with another tunnel we consider it failed if (it.second.first) { if (it.second.first->GetState () == eTunnelStateTestFailed) { it.second.first->SetState (eTunnelStateFailed); std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (it.second.first); } else it.second.first->SetState (eTunnelStateTestFailed); } if (it.second.second) { if (it.second.second->GetState () == eTunnelStateTestFailed) { it.second.second->SetState (eTunnelStateFailed); { std::unique_lock<std::mutex> l(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } else it.second.second->SetState (eTunnelStateTestFailed); } } m_Tests.clear (); // new tests auto it1 = m_OutboundTunnels.begin (); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) { bool failed = false; if ((*it1)->IsFailed ()) { failed = true; it1++; } if ((*it2)->IsFailed ()) { failed = true; it2++; } if (!failed) { uint32_t msgID; RAND_bytes ((uint8_t *)&msgID, 4); m_Tests[msgID] = std::make_pair (*it1, *it2); (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), CreateDeliveryStatusMsg (msgID)); it1++; it2++; } } }
int dtls1_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; int bs,i,ii,j,k,n=0; const EVP_CIPHER *enc; if (send) { if (s->write_hash != NULL) n=EVP_MD_size(s->write_hash); ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) enc=NULL; else { enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); if ( rec->data != rec->input) /* we can't write into the input stream */ fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__, __LINE__); else if ( EVP_CIPHER_block_size(ds->cipher) > 1) { if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher))) return -1; } } } else { if (s->read_hash != NULL) n=EVP_MD_size(s->read_hash); ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) enc=NULL; else enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); } #ifdef KSSL_DEBUG printf("dtls1_enc(%d)\n", send); #endif /* KSSL_DEBUG */ if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { memmove(rec->data,rec->input,rec->length); rec->input=rec->data; } else { l=rec->length; bs=EVP_CIPHER_block_size(ds->cipher); if ((bs != 1) && send) { i=bs-((int)l%bs); /* Add weird padding of upto 256 bytes */ /* we need to add 'i' padding bytes of value j */ j=i-1; if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) j++; } for (k=(int)l; k<(int)(l+i); k++) rec->input[k]=j; l+=i; rec->length+=i; } #ifdef KSSL_DEBUG { unsigned long ui; printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", (void *)ds,rec->data,rec->input,l); printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", ds->buf_len, ds->cipher->key_len, (unsigned long)DES_KEY_SZ, (unsigned long)DES_SCHEDULE_SZ, ds->cipher->iv_len); printf("\t\tIV: "); for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); printf("\n"); printf("\trec->input="); for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]); printf("\n"); } #endif /* KSSL_DEBUG */ if (!send) { if (l == 0 || l%bs != 0) { SSLerr(SSL_F_DTLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); return 0; } } EVP_Cipher(ds,rec->data,rec->input,l); #ifdef KSSL_DEBUG { unsigned long ki; printf("\trec->data="); for (ki=0; ki<l; ki++) printf(" %02x", rec->data[ki]); printf("\n"); } #endif /* KSSL_DEBUG */ if ((bs != 1) && !send) { ii=i=rec->data[l-1]; /* padding_length */ i++; if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) { /* First packet is even in size, so check */ if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) i--; } /* TLS 1.0 does not bound the number of padding bytes by the block size. * All of them must have value 'padding_length'. */ if (i > (int)rec->length) { /* Incorrect padding. SSLerr() and ssl3_alert are done * by caller: we don't want to reveal whether this is * a decryption error or a MAC verification failure * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ return -1; } for (j=(int)(l-i); j<(int)l; j++) { if (rec->data[j] != ii) { /* Incorrect padding */ return -1; } } rec->length-=i; rec->data += bs; /* skip the implicit IV */ rec->input += bs; rec->length -= bs; } } return(1); }
/* * Wrap data in PKCS#7 envelopes and base64-encode the result. * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in * GetCert and GETCrl. */ int pkcs7_wrap(struct scep *s, struct sscep_ctx *ctx, struct sscep_operation_info *op_info) { BIO *databio = NULL; BIO *encbio = NULL; BIO *pkcs7bio = NULL; BIO *memorybio = NULL; BIO *outbio = NULL; unsigned char *buffer = NULL; int len = 0; STACK_OF(X509) *recipients = NULL; PKCS7 *p7enc = NULL; PKCS7_SIGNER_INFO *si; STACK_OF(X509_ATTRIBUTE) *attributes; X509 *signercert = NULL; EVP_PKEY *signerkey = NULL; int ret = SCEP_PKISTATUS_P7; char *payload = NULL; int payload_len; /* Create a new sender nonce for all messages * XXXXXXXXXXXXXX should it be per transaction? */ s->sender_nonce_len = 16; free(s->sender_nonce);/* Clean up from previous runs */ s->sender_nonce = (char *)malloc(s->sender_nonce_len * sizeof(char)); RAND_bytes((unsigned char *) s->sender_nonce, s->sender_nonce_len); /* Prepare data payload */ switch (s->request_type) { case SCEP_REQUEST_PKCSREQ: /* * Set printable message type * We set this later as an autheticated attribute * "messageType". */ s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating inner PKCS#7"); } /* Read request in memory bio */ databio = BIO_new(BIO_s_mem()); if (i2d_X509_REQ_bio(databio, op_info->request) <= 0) { qeo_log_e("error writing certificate request in bio"); goto error; } (void)BIO_flush(databio); break; case SCEP_REQUEST_GETCERTINIT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating inner PKCS#7"); } /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if (i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) { qeo_log_e("error writing GetCertInitial data in bio"); goto error; } (void)BIO_flush(databio); break; } /* Below this is the common code for all request_type */ /* Read in the payload */ payload_len = BIO_get_mem_data(databio, &payload); if (ctx->verbose){ qeo_log_i("data payload size: %d bytes", payload_len); } /* Create encryption certificate stack */ if ((recipients = sk_X509_new(NULL) ) == NULL) { qeo_log_e("error creating certificate stack"); goto error; } if (sk_X509_push(recipients, op_info->racert) <= 0) { qeo_log_e("error adding recipient encryption certificate"); goto error; } /* Create BIO for encryption */ if ((encbio = BIO_new_mem_buf(payload, payload_len)) == NULL ) { qeo_log_e("error creating data bio"); goto error; } /* Encrypt */ if (!(p7enc = PKCS7_encrypt(recipients, encbio, ctx->enc_alg, PKCS7_BINARY))) { qeo_log_e("request payload encrypt failed"); goto error; } if (ctx->verbose){ qeo_log_i("successfully encrypted payload"); } /* Write encrypted data */ memorybio = BIO_new(BIO_s_mem()); if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { qeo_log_e("error writing encrypted data"); goto error; } (void)BIO_flush(memorybio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); len = BIO_get_mem_data(memorybio, &buffer); BIO_free(memorybio); memorybio=NULL; if (ctx->verbose){ qeo_log_i("envelope size: %d bytes", len); } if (ctx->debug) { qeo_log_i("printing PEM fomatted PKCS#7"); PEM_write_PKCS7(stdout, p7enc); } /* Create outer PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating outer PKCS#7"); } s->request_p7 = PKCS7_new(); if (s->request_p7 == NULL ) { qeo_log_e("failed creating PKCS#7 for signing"); goto error; } if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { qeo_log_e("failed setting PKCS#7 type"); goto error; } /* Add signer certificate and signature */ PKCS7_add_certificate(s->request_p7, signercert); if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, ctx->sig_alg)) == NULL ) { qeo_log_e("error adding PKCS#7 signature"); goto error; } if (ctx->verbose){ qeo_log_i("signature added successfully"); } /* Set signed attributes */ if (ctx->verbose){ qeo_log_i("adding signed attributes"); } attributes = sk_X509_ATTRIBUTE_new_null(); add_attribute_string(attributes, ctx->nid_transId, s->transaction_id, ctx); add_attribute_string(attributes, ctx->nid_messageType, s->request_type_str, ctx); add_attribute_octet(attributes, ctx->nid_senderNonce, s->sender_nonce, s->sender_nonce_len, ctx); PKCS7_set_signed_attributes(si, attributes); sk_X509_ATTRIBUTE_pop_free(attributes, X509_ATTRIBUTE_free); /* Add contentType */ if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { qeo_log_e("error adding NID_pkcs9_contentType"); goto error; } /* Create new content */ if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { qeo_log_e("failed setting PKCS#7 content type"); goto error; } /* Write data */ pkcs7bio = PKCS7_dataInit(s->request_p7, NULL ); if (pkcs7bio == NULL ) { qeo_log_e("error opening bio for writing PKCS#7 data"); goto error; } if (len != BIO_write(pkcs7bio, buffer, len)) { qeo_log_e("error writing PKCS#7 data"); goto error; } if (ctx->verbose){ qeo_log_i("PKCS#7 data written successfully"); } /* Finalize PKCS#7 */ if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { qeo_log_e("error finalizing outer PKCS#7"); goto error; } if (ctx->debug) { qeo_log_i("printing PEM fomatted PKCS#7"); PEM_write_PKCS7(stdout, s->request_p7); } /* base64-encode the data */ if (ctx->verbose){ qeo_log_i("applying base64 encoding"); } /* Create base64 filtering bio */ memorybio = BIO_new(BIO_s_mem()); outbio = BIO_push(BIO_new(BIO_f_base64()), memorybio); /* Copy PKCS#7 */ i2d_PKCS7_bio(outbio, s->request_p7); (void)BIO_flush(outbio); payload_len = BIO_get_mem_data(memorybio, &payload); s->request_payload = (char*) malloc(sizeof(char)*payload_len); if (!s->request_payload){ goto error; } s->request_len = payload_len; memcpy(s->request_payload, payload, s->request_len); if (ctx->verbose){ qeo_log_i("base64 encoded payload size: %d bytes", payload_len); } ret = 0; error: BIO_free(databio); BIO_free(encbio); BIO_free_all(pkcs7bio); BIO_free(memorybio); BIO_free(outbio); if (recipients != NULL){ sk_X509_free(recipients);/* Only free the stack, not the certificates */ } PKCS7_free(p7enc); OPENSSL_free(buffer); return ret; }
// Generate random data bool OSSLRNG::generateRandom(ByteString& data, const size_t len) { data.wipe(len); return RAND_bytes(&data[0], len); }
int pkey_GOST_ECcp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key, size_t key_len) { GOST_KEY_TRANSPORT *gkt = NULL; EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); int pkey_nid = EVP_PKEY_base_id(pubk); ASN1_OBJECT *crypt_params_obj = (pkey_nid == NID_id_GostR3410_2001) ? OBJ_nid2obj(NID_id_Gost28147_89_CryptoPro_A_ParamSet) : OBJ_nid2obj(NID_id_tc26_gost_28147_param_Z); const struct gost_cipher_info *param = get_encryption_params(crypt_params_obj); unsigned char ukm[8], shared_key[32], crypted_key[44]; int ret = 0; int key_is_ephemeral = 1; gost_ctx cctx; EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); if (data->shared_ukm) { memcpy(ukm, data->shared_ukm, 8); } else if (out) { if (RAND_bytes(ukm, 8) <= 0) { GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_RNG_ERROR); return 0; } } /* Check for private key in the peer_key of context */ if (sec_key) { key_is_ephemeral = 0; if (!gost_get0_priv_key(sec_key)) { GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); goto err; } } else { key_is_ephemeral = 1; if (out) { sec_key = EVP_PKEY_new(); EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new()); EVP_PKEY_copy_parameters(sec_key, pubk); if (!gost_ec_keygen(EVP_PKEY_get0(sec_key))) { goto err; } } } if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list) { param = gost_cipher_list; } if (out) { int dgst_nid = NID_undef; EVP_PKEY_get_default_digest_nid(pubk, &dgst_nid); if (!VKO_compute_key(shared_key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)), EVP_PKEY_get0(sec_key), ukm, dgst_nid)) { GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_ERROR_COMPUTING_SHARED_KEY); goto err; } gost_init(&cctx, param->sblock); keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key); } gkt = GOST_KEY_TRANSPORT_new(); if (!gkt) { goto err; } if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { goto err; } if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { goto err; } if (!ASN1_OCTET_STRING_set (gkt->key_info->encrypted_key, crypted_key + 8, 32)) { goto err; } if (key_is_ephemeral) { if (!X509_PUBKEY_set (&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk)) { GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_CANNOT_PACK_EPHEMERAL_KEY); goto err; } } ASN1_OBJECT_free(gkt->key_agreement_info->cipher); gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); if (key_is_ephemeral) EVP_PKEY_free(sec_key); if (!key_is_ephemeral) { /* Set control "public key from client certificate used" */ if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) { GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); goto err; } } if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0) ret = 1; GOST_KEY_TRANSPORT_free(gkt); return ret; err: if (key_is_ephemeral) EVP_PKEY_free(sec_key); GOST_KEY_TRANSPORT_free(gkt); return -1; }
static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, size_t keylen, uint64_t N, uint64_t r, uint64_t p) { X509_ALGOR *keyfunc = NULL; SCRYPT_PARAMS *sparam = NULL; sparam = SCRYPT_PARAMS_new(); if (sparam == NULL) goto merr; if (!saltlen) saltlen = PKCS5_SALT_LEN; /* This will either copy salt or grow the buffer */ if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) goto merr; if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0) goto err; if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0) goto merr; if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0) goto merr; if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0) goto merr; /* If have a key len set it up */ if (keylen > 0) { sparam->keyLength = ASN1_INTEGER_new(); if (sparam->keyLength == NULL) goto merr; if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0) goto merr; } /* Finally setup the keyfunc structure */ keyfunc = X509_ALGOR_new(); if (keyfunc == NULL) goto merr; keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt); /* Encode SCRYPT_PARAMS into parameter of pbe2 */ if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam, &keyfunc->parameter) == NULL) goto merr; SCRYPT_PARAMS_free(sparam); return keyfunc; merr: ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE); err: SCRYPT_PARAMS_free(sparam); X509_ALGOR_free(keyfunc); return NULL; }
static int sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) { struct sm_cwa_session *cwa_session = &sm_info->session.cwa; struct sm_cwa_keyset *cwa_keyset = &sm_info->session.cwa.cwa_keyset; scconf_block *sm_conf_block = NULL, **blocks; struct sc_crt *crt_at = &sm_info->session.cwa.params.crt_at; const char *value = NULL; char name[128]; unsigned char hex[48]; size_t hex_len = sizeof(hex); int rv, ii, ref = crt_at->refs[0] & IASECC_OBJECT_REF_MAX; for (ii = 0; ctx->conf_blocks[ii]; ii++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm_info->config_section); if (blocks) { sm_conf_block = blocks[0]; free(blocks); } if (sm_conf_block) break; } sc_log(ctx, "CRT(algo:%X,ref:%X)", crt_at->algo, crt_at->refs[0]); /* Keyset ENC */ if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL)) snprintf(name, sizeof(name), "keyset_%s_%02i_enc", sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref); else snprintf(name, sizeof(name), "keyset_%02i_enc", ref); value = scconf_get_str(sm_conf_block, name, NULL); if (!value) { sc_log(ctx, "No %s value in OpenSC config", name); return SC_ERROR_SM_KEYSET_NOT_FOUND; } sc_log(ctx, "keyset::enc(%i) %s", strlen(value), value); if (strlen(value) == 16) { memcpy(cwa_keyset->enc, value, 16); } else { hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { sc_log(ctx, "SM get %s: hex to bin failed for '%s'; error %i", name, value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } sc_log(ctx, "ENC(%i) %s", hex_len, sc_dump_hex(hex, hex_len)); if (hex_len != 16) return SC_ERROR_INVALID_DATA; memcpy(cwa_keyset->enc, hex, hex_len); } sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->enc, 16)); /* Keyset MAC */ if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL)) snprintf(name, sizeof(name), "keyset_%s_%02i_mac", sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref); else snprintf(name, sizeof(name), "keyset_%02i_mac", ref); value = scconf_get_str(sm_conf_block, name, NULL); if (!value) { sc_log(ctx, "No %s value in OpenSC config", name); return SC_ERROR_SM_KEYSET_NOT_FOUND; } sc_log(ctx, "keyset::mac(%i) %s", strlen(value), value); if (strlen(value) == 16) { memcpy(cwa_keyset->mac, value, 16); } else { hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { sc_log(ctx, "SM get '%s': hex to bin failed for '%s'; error %i", name, value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } sc_log(ctx, "MAC(%i) %s", hex_len, sc_dump_hex(hex, hex_len)); if (hex_len != 16) return SC_ERROR_INVALID_DATA; memcpy(cwa_keyset->mac, hex, hex_len); } sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->mac, 16)); cwa_keyset->sdo_reference = crt_at->refs[0]; /* IFD parameters */ //memset(cwa_session, 0, sizeof(struct sm_cwa_session)); value = scconf_get_str(sm_conf_block, "ifd_serial", NULL); if (!value) return SC_ERROR_SM_IFD_DATA_MISSING; hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { sc_log(ctx, "SM get 'ifd_serial': hex to bin failed for '%s'; error %i", value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } if (hex_len != sizeof(cwa_session->ifd.sn)) { sc_log(ctx, "SM get 'ifd_serial': invalid IFD serial length: %i", hex_len); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } memcpy(cwa_session->ifd.sn, hex, hex_len); rv = RAND_bytes(cwa_session->ifd.rnd, 8); if (!rv) { sc_log(ctx, "Generate random error: %i", rv); return SC_ERROR_SM_RAND_FAILED; } rv = RAND_bytes(cwa_session->ifd.k, 32); if (!rv) { sc_log(ctx, "Generate random error: %i", rv); return SC_ERROR_SM_RAND_FAILED; } sc_log(ctx, "IFD.Serial: %s", sc_dump_hex(cwa_session->ifd.sn, sizeof(cwa_session->ifd.sn))); sc_log(ctx, "IFD.Rnd: %s", sc_dump_hex(cwa_session->ifd.rnd, sizeof(cwa_session->ifd.rnd))); sc_log(ctx, "IFD.K: %s", sc_dump_hex(cwa_session->ifd.k, sizeof(cwa_session->ifd.k))); return SC_SUCCESS; }
static int client_master_key(SSL *s) { unsigned char *buf; unsigned char *p,*d; int clear,enc,karg,i; SSL_SESSION *sess; const EVP_CIPHER *c; const EVP_MD *md; buf=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { if (!ssl_cipher_get_evp(s->session,&c,&md,NULL)) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); return(-1); } sess=s->session; p=buf; d=p+10; *(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */ i=ssl_put_cipher_by_char(s,sess->cipher,p); p+=i; /* make key_arg data */ i=EVP_CIPHER_iv_length(c); sess->key_arg_length=i; if (i > SSL_MAX_KEY_ARG_LENGTH) { ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } if (i > 0) if (RAND_pseudo_bytes(sess->key_arg,i) <= 0) return -1; /* make a master key */ i=EVP_CIPHER_key_length(c); sess->master_key_length=i; if (i > 0) { if (i > (int)sizeof(sess->master_key)) { ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } if (RAND_bytes(sess->master_key,i) <= 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); } } if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) enc=8; else if (SSL_C_IS_EXPORT(sess->cipher)) enc=5; else enc=i; if ((int)i < enc) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR); return(-1); } clear=i-enc; s2n(clear,p); memcpy(d,sess->master_key,(unsigned int)clear); d+=clear; enc=ssl_rsa_public_encrypt(sess->sess_cert,enc, &(sess->master_key[clear]),d, (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING); if (enc <= 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR); return(-1); } #ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++; if (s->options & SSL_OP_PKCS1_CHECK_2) sess->master_key[clear]++; #endif s2n(enc,p); d+=enc; karg=sess->key_arg_length; s2n(karg,p); /* key arg size */ if (karg > (int)sizeof(sess->key_arg)) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } memcpy(d,sess->key_arg,(unsigned int)karg); d+=karg; s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B; s->init_num=d-buf; s->init_off=0; } /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */ return(ssl2_do_write(s)); }
int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, const uint8_t *from, unsigned flen, const uint8_t *param, unsigned plen, const EVP_MD *md, const EVP_MD *mgf1md) { unsigned i, emlen, mdlen; uint8_t *db, *seed; uint8_t *dbmask = NULL, seedmask[EVP_MAX_MD_SIZE]; int ret = 0; if (md == NULL) { md = EVP_sha1(); } if (mgf1md == NULL) { mgf1md = md; } mdlen = EVP_MD_size(md); if (tlen < 2 * mdlen + 2) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } emlen = tlen - 1; if (flen > emlen - 2 * mdlen - 1) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } if (emlen < 2 * mdlen + 1) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } to[0] = 0; seed = to + 1; db = to + mdlen + 1; if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) { return 0; } memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); db[emlen - flen - mdlen - 1] = 0x01; memcpy(db + emlen - flen - mdlen, from, flen); if (!RAND_bytes(seed, mdlen)) { return 0; } dbmask = OPENSSL_malloc(emlen - mdlen); if (dbmask == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1, ERR_R_MALLOC_FAILURE); return 0; } if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0) { goto out; } for (i = 0; i < emlen - mdlen; i++) { db[i] ^= dbmask[i]; } if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0) { goto out; } for (i = 0; i < mdlen; i++) { seed[i] ^= seedmask[i]; } ret = 1; out: OPENSSL_free(dbmask); return ret; }
int main() { BIO *bio; RSA *rsa=0, *rsa_pub, *rsa_priv=0; char buf[4096], enc[4096], dec[4096]; BUF_MEM *ptr; int len, enc_len, dec_len; int i; BF_KEY key; char ivec_orig[8] = {1, 2, 3, 4, 5, 6, 7, 8}, ivec[8]; do { //OpenSSL_add_all_algorithms(); //OpenSSL_add_all_ciphers(); //OpenSSL_add_all_digests(); printf("generate_key:\n"); rsa = RSA_generate_key(1024, 3, gen_cb, 0); printf("\n"); printf("pem public key:\n"); bio = BIO_new(BIO_s_mem()); i = PEM_write_bio_RSAPublicKey(bio, rsa); BIO_flush(bio); i = BIO_get_mem_ptr(bio, &ptr); printf("pem public key len=%d\n", ptr->length); fwrite(ptr->data, ptr->length, 1, stdout); len = ptr->length; memcpy(buf, ptr->data, len); BIO_free(bio); printf("\n"); bio = BIO_new_mem_buf(buf, len); rsa_pub = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0); BIO_free(bio); printf("pem private key:\n"); bio = BIO_new(BIO_s_mem()); i = PEM_write_bio_RSAPrivateKey(bio, rsa, 0, 0, 0, 0, 0); BIO_flush(bio); i = BIO_get_mem_ptr(bio, &ptr); printf("pem private key i=%d len=%d\n", i, ptr->length); fwrite(ptr->data, ptr->length, 1, stdout); len = ptr->length; memcpy(buf, ptr->data, len); BIO_free(bio); printf("\n"); bio = BIO_new_mem_buf(buf, len); rsa_priv = PEM_read_bio_RSAPrivateKey(bio, 0, 0, 0); BIO_free(bio); /* encrypt */ printf("buffer:\n"); len = sprintf(buf, "1234567890123456"); len = 128/8; RAND_bytes(buf, len); printf("buf_len=%d\n", len); //printf("%s", dec); for(i=0; i<len; i++) { printf("%02x", (unsigned int)buf[i]&0xff); } printf("\n"); printf("public_encrypt:\n"); memset(enc, 0, sizeof(enc)); enc_len = RSA_public_encrypt(len, buf, enc, rsa_pub, RSA_PKCS1_OAEP_PADDING); if( enc_len < 0 ) { printf("err=%ld\n", ERR_get_error()); break; } printf("enc_len=%d\n", enc_len); for(i=0; i<enc_len; i++) { printf("%02x", (unsigned int)enc[i]&0xff); } printf("\n"); printf("public_decrypt:\n"); memset(dec, 0, sizeof(dec)); dec_len = RSA_private_decrypt(enc_len, enc, dec, rsa_priv, RSA_PKCS1_OAEP_PADDING); if( dec_len < 0 ) { printf("err=%ld\n", ERR_get_error()); break; } printf("dec_len=%d\n", dec_len); for(i=0; i<dec_len; i++) { printf("%02x", (unsigned int)dec[i]&0xff); } printf("\n"); // blowfish BF_set_key(&key, dec_len, dec); i = 0; memcpy(ivec, ivec_orig, 8); memset(buf, 0, sizeof(buf)); BF_cfb64_encrypt(enc, buf, enc_len, &key, ivec, &i, BF_ENCRYPT); printf("BF_cfb64_encrypt:\n"); for(i=0; i<enc_len; i++) { printf("%02x", (unsigned int)buf[i]&0xff); } printf("\n"); i = 0; memcpy(ivec, ivec_orig, 8); memset(enc, 0, sizeof(buf)); BF_cfb64_encrypt(buf, enc, enc_len, &key, ivec, &i, BF_DECRYPT); printf("BF_cfb64_decrypt:\n"); for(i=0; i<enc_len; i++) { printf("%02x", (unsigned int)enc[i]&0xff); } printf("\n"); } while(0); if( rsa ) { RSA_free(rsa); } return 0; }
int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen) { int i; int ret = 0; size_t maskedDBLen, MSBits, emLen; size_t hLen; unsigned char *H, *salt = NULL, *p; EVP_MD_CTX ctx; if (mgf1Hash == NULL) { mgf1Hash = Hash; } hLen = EVP_MD_size(Hash); /* Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is maximized * -N reserved */ if (sLen == -1) { sLen = hLen; } else if (sLen == -2) { sLen = -2; } else if (sLen < -2) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1, RSA_R_SLEN_CHECK_FAILED); goto err; } if (BN_is_zero(rsa->n)) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1, RSA_R_EMPTY_PUBLIC_KEY); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = RSA_size(rsa); if (MSBits == 0) { assert(emLen >= 1); *EM++ = 0; emLen--; } if (sLen == -2) { if (emLen < hLen + 2) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } sLen = emLen - hLen - 2; } else if (emLen < hLen + sLen + 2) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (!salt) { OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1, ERR_R_MALLOC_FAILURE); goto err; } if (!RAND_bytes(salt, sLen)) { goto err; } } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; EVP_MD_CTX_init(&ctx); if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) || !EVP_DigestUpdate(&ctx, mHash, hLen)) { goto err; } if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) { goto err; } if (!EVP_DigestFinal_ex(&ctx, H, NULL)) { goto err; } EVP_MD_CTX_cleanup(&ctx); /* Generate dbMask in place then perform XOR on it */ if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) { goto err; } p = EM; /* Initial PS XORs with all zeroes which is a NOP so just update * pointer. Note from a test above this value is guaranteed to * be non-negative. */ p += emLen - sLen - hLen - 2; *p++ ^= 0x1; if (sLen > 0) { for (i = 0; i < sLen; i++) { *p++ ^= salt[i]; } } if (MSBits) { EM[0] &= 0xFF >> (8 - MSBits); } /* H is already in place so just set final 0xbc */ EM[emLen - 1] = 0xbc; ret = 1; err: OPENSSL_free(salt); return ret; }
/* Open the SSL module */ PUBLIC int sslOpen() { RandBuf randBuf; X509_STORE *store; uchar resume[16]; char *ciphers; trace(7, "Initializing SSL"); randBuf.now = time(0); randBuf.pid = getpid(); RAND_seed((void*) &randBuf, sizeof(randBuf)); #if ME_UNIX_LIKE trace(6, "OpenSsl: Before calling RAND_load_file"); RAND_load_file("/dev/urandom", 256); trace(6, "OpenSsl: After calling RAND_load_file"); #endif CRYPTO_malloc_init(); #if !ME_WIN_LIKE OpenSSL_add_all_algorithms(); #endif SSL_library_init(); SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); if ((sslctx = SSL_CTX_new(SSLv23_server_method())) == 0) { error("Unable to create SSL context"); return -1; } /* Set the server certificate and key files */ if (*ME_GOAHEAD_SSL_KEY && sslSetKeyFile(ME_GOAHEAD_SSL_KEY) < 0) { sslClose(); return -1; } if (*ME_GOAHEAD_SSL_CERTIFICATE && sslSetCertFile(ME_GOAHEAD_SSL_CERTIFICATE) < 0) { sslClose(); return -1; } if (ME_GOAHEAD_SSL_VERIFY_PEER) { SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verifyClientCertificate); SSL_CTX_set_verify_depth(sslctx, VERIFY_DEPTH); } else { SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, verifyClientCertificate); } /* Set the client certificate verification locations */ if (ME_GOAHEAD_SSL_AUTHORITY && *ME_GOAHEAD_SSL_AUTHORITY) { if ((!SSL_CTX_load_verify_locations(sslctx, ME_GOAHEAD_SSL_AUTHORITY, NULL)) || (!SSL_CTX_set_default_verify_paths(sslctx))) { error("Unable to read cert verification locations"); sslClose(); return -1; } /* Define the list of CA certificates to send to the client before they send their client certificate for validation */ SSL_CTX_set_client_CA_list(sslctx, SSL_load_client_CA_file(ME_GOAHEAD_SSL_AUTHORITY)); } if (ME_GOAHEAD_SSL_REVOKE && *ME_GOAHEAD_SSL_REVOKE) { store = SSL_CTX_get_cert_store(sslctx); if (!X509_STORE_load_locations(store, ME_GOAHEAD_SSL_REVOKE, 0)) { error("Cannot load certificate revoke list: %s", ME_GOAHEAD_SSL_REVOKE); sslClose(); return -1; } } /* Configure DH parameters */ dhKey = getDhKey(); SSL_CTX_set_tmp_dh_callback(sslctx, dhcallback); /* Configure cipher suite */ if (ME_GOAHEAD_SSL_CIPHERS && *ME_GOAHEAD_SSL_CIPHERS) { ciphers = ME_GOAHEAD_SSL_CIPHERS; } else { ciphers = OPENSSL_DEFAULT_CIPHERS; } ciphers = mapCipherNames(ciphers); trace(5, "Using OpenSSL ciphers: %s", ciphers); if (SSL_CTX_set_cipher_list(sslctx, ciphers) != 1) { error("Unable to set cipher list \"%s\"", ciphers); sslClose(); wfree(ciphers); return -1; } wfree(ciphers); /* Define default OpenSSL options */ SSL_CTX_set_options(sslctx, SSL_OP_ALL); /* Ensure we generate a new private key for each connection */ SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE); /* Define a session reuse context */ RAND_bytes(resume, sizeof(resume)); SSL_CTX_set_session_id_context(sslctx, resume, sizeof(resume)); /* Elliptic Curve initialization */ #if SSL_OP_SINGLE_ECDH_USE #ifdef SSL_CTX_set_ecdh_auto SSL_CTX_set_ecdh_auto(sslctx, 1); #else { EC_KEY *ecdh; cchar *name; int nid; name = ME_GOAHEAD_SSL_CURVE; if ((nid = OBJ_sn2nid(name)) == 0) { error("Unknown curve name \"%s\"", name); sslClose(); return -1; } if ((ecdh = EC_KEY_new_by_curve_name(nid)) == 0) { error("Unable to create curve \"%s\"", name); sslClose(); return -1; } SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_ECDH_USE); SSL_CTX_set_tmp_ecdh(sslctx, ecdh); EC_KEY_free(ecdh); } #endif #endif SSL_CTX_set_mode(sslctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); #ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING SSL_CTX_set_options(sslctx, SSL_OP_MSIE_SSLV2_RSA_PADDING); #endif #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(sslctx, SSL_MODE_RELEASE_BUFFERS); #endif #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE SSL_CTX_set_mode(sslctx, SSL_OP_CIPHER_SERVER_PREFERENCE); #endif /* Select the required protocols Disable both SSLv2 and SSLv3 by default - they are insecure */ SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2); SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3); #if defined(SSL_OP_NO_TLSv1) && ME_GOAHEAD_SSL_NO_V1 SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1); #endif #if defined(SSL_OP_NO_TLSv1_1) && ME_GOAHEAD_SSL_NO_V1_1 SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_1); #endif #if defined(SSL_OP_NO_TLSv1_2) && ME_GOAHEAD_SSL_NO_V1_2 SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_2); #endif #if defined(SSL_OP_NO_TICKET) /* Ticket based session reuse is enabled by default */ #if defined(ME_GOAHEAD_SSL_TICKET) if (ME_GOAHEAD_SSL_TICKET) { SSL_CTX_clear_options(sslctx, SSL_OP_NO_TICKET); } else { SSL_CTX_set_options(sslctx, SSL_OP_NO_TICKET); } #else SSL_CTX_clear_options(sslctx, SSL_OP_NO_TICKET); #endif #endif #if defined(SSL_OP_NO_COMPRESSION) /* CRIME attack targets compression */ SSL_CTX_clear_options(sslctx, SSL_OP_NO_COMPRESSION); #endif #if defined(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) /* Disables a countermeasure against a SSL 3.0/TLS 1.0 protocol vulnerability affecting CBC ciphers. Defaults to true. */ #if defined(ME_GOAHEAD_SSL_EMPTY_FRAGMENTS) if (ME_GOAHEAD_SSL_EMPTY_FRAGMENTS) { /* SSL_OP_ALL disables empty fragments. Only needed for ancient browsers like IE-6 on SSL-3.0/TLS-1.0 */ SSL_CTX_clear_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); } else { SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); } #else SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); #endif #endif #if defined(ME_GOAHEAD_SSL_CACHE) /* Set the number of sessions supported. Default in OpenSSL is 20K. */ SSL_CTX_sess_set_cache_size(sslctx, ME_GOAHEAD_SSL_CACHE); #else SSL_CTX_sess_set_cache_size(sslctx, 256); #endif return 0; }
static int ltm_rsa_public_encrypt(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding) { unsigned char *p, *p0; int res; size_t size, padlen; mp_int enc, dec, n, e; if (padding != RSA_PKCS1_PADDING) return -1; mp_init_multi(&n, &e, &enc, &dec, NULL); size = RSA_size(rsa); if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen) { mp_clear_multi(&n, &e, &enc, &dec); return -2; } BN2mpz(&n, rsa->n); BN2mpz(&e, rsa->e); p = p0 = malloc(size - 1); if (p0 == NULL) { mp_clear_multi(&e, &n, &enc, &dec, NULL); return -3; } padlen = size - flen - 3; *p++ = 2; if (RAND_bytes(p, padlen) != 1) { mp_clear_multi(&e, &n, &enc, &dec, NULL); free(p0); return -4; } while(padlen) { if (*p == 0) *p = 1; padlen--; p++; } *p++ = 0; memcpy(p, from, flen); p += flen; assert((p - p0) == size - 1); mp_read_unsigned_bin(&dec, p0, size - 1); free(p0); res = mp_exptmod(&dec, &e, &n, &enc); mp_clear_multi(&dec, &e, &n, NULL); if (res != 0) { mp_clear(&enc); return -4; } { size_t ssize; ssize = mp_unsigned_bin_size(&enc); assert(size >= ssize); mp_to_unsigned_bin(&enc, to); size = ssize; } mp_clear(&enc); return size; }
static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, pem_password_cb *cb, void *u) { int outlen = 24, pklen; unsigned char *p, *salt = NULL; EVP_CIPHER_CTX cctx; EVP_CIPHER_CTX_init(&cctx); if (enclevel) outlen += PVK_SALTLEN; pklen = do_i2b(NULL, pk, 0); if (pklen < 0) return -1; outlen += pklen; if (!out) return outlen; if (*out) p = *out; else { p = OPENSSL_malloc(outlen); if (!p) { PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE); return -1; } *out = p; } write_ledword(&p, MS_PVKMAGIC); write_ledword(&p, 0); if (pk->type == EVP_PKEY_DSA) write_ledword(&p, MS_KEYTYPE_SIGN); else write_ledword(&p, MS_KEYTYPE_KEYX); write_ledword(&p, enclevel ? 1 : 0); write_ledword(&p, enclevel ? PVK_SALTLEN: 0); write_ledword(&p, pklen); if (enclevel) { if (RAND_bytes(p, PVK_SALTLEN) <= 0) goto error; salt = p; p += PVK_SALTLEN; } do_i2b(&p, pk, 0); if (enclevel == 0) return outlen; else { char psbuf[PEM_BUFSIZE]; unsigned char keybuf[20]; int enctmplen, inlen; if (cb) inlen=cb(psbuf,PEM_BUFSIZE,1,u); else inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u); if (inlen <= 0) { PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ); goto error; } if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, (unsigned char *)psbuf, inlen)) goto error; if (enclevel == 1) memset(keybuf + 5, 0, 11); p = salt + PVK_SALTLEN + 8; if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) goto error; OPENSSL_cleanse(keybuf, 20); if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8)) goto error; if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen)) goto error; } EVP_CIPHER_CTX_cleanup(&cctx); return outlen; error: EVP_CIPHER_CTX_cleanup(&cctx); return -1; }
static krb5_error_code kcm_ccache_alloc(krb5_context context, const char *name, kcm_ccache *ccache) { kcm_ccache slot = NULL, p; krb5_error_code ret; int new_slot = 0; *ccache = NULL; /* First, check for duplicates */ HEIMDAL_MUTEX_lock(&ccache_mutex); ret = 0; for (p = ccache_head; p != NULL; p = p->next) { if (p->flags & KCM_FLAGS_VALID) { if (strcmp(p->name, name) == 0) { ret = KRB5_CC_WRITE; break; } } else if (slot == NULL) slot = p; } if (ret) goto out; /* * Create an enpty slot for us. */ if (slot == NULL) { slot = (kcm_ccache_data *)malloc(sizeof(*slot)); if (slot == NULL) { ret = KRB5_CC_NOMEM; goto out; } slot->next = ccache_head; HEIMDAL_MUTEX_init(&slot->mutex); new_slot = 1; } RAND_bytes(slot->uuid, sizeof(slot->uuid)); slot->name = strdup(name); if (slot->name == NULL) { ret = KRB5_CC_NOMEM; goto out; } slot->refcnt = 1; slot->flags = KCM_FLAGS_VALID; slot->mode = S_IRUSR | S_IWUSR; slot->uid = -1; slot->gid = -1; slot->client = NULL; slot->server = NULL; slot->creds = NULL; slot->key.keytab = NULL; slot->tkt_life = 0; slot->renew_life = 0; if (new_slot) ccache_head = slot; *ccache = slot; HEIMDAL_MUTEX_unlock(&ccache_mutex); return 0; out: HEIMDAL_MUTEX_unlock(&ccache_mutex); if (new_slot && slot != NULL) { HEIMDAL_MUTEX_destroy(&slot->mutex); free(slot); } return ret; }