result_t PKey::sign(Buffer_base *data, obj_ptr<Buffer_base> &retVal, exlib::AsyncEvent *ac) { if (switchToAsync(ac)) return CHECK_ERROR(CALL_E_NOSYNC); result_t hr; bool priv; hr = isPrivate(priv); if (hr < 0) return hr; if (!priv) return CHECK_ERROR(CALL_E_INVALID_CALL); int ret; std::string str; std::string output; size_t olen; data->toString(str); output.resize(POLARSSL_PREMASTER_SIZE); ret = pk_sign(&m_key, POLARSSL_MD_NONE, (const unsigned char *)str.c_str(), str.length(), (unsigned char *)&output[0], &olen, ctr_drbg_random, &g_ssl.ctr_drbg); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); output.resize(olen); retVal = new Buffer(output); return 0; }
int pkb_update_dns(struct pk_manager* pkm) { int j, len, bogus, rlen; struct pk_tunnel* fe_list[1024]; /* Magic, bounded by address_list[] below */ struct pk_tunnel** fes; struct pk_tunnel* fe; struct pk_pagekite* kite; char printip[128], get_result[10240], *result, *lastup; char address_list[1024], payload[2048], signature[2048], url[2048], *alp; PK_TRACE_FUNCTION; if (time(0) < pkm->last_dns_update + PK_DDNS_UPDATE_INTERVAL_MIN) return 0; address_list[0] = '\0'; alp = address_list; fes = fe_list; *fes = NULL; bogus = 0; for (j = 0, fe = pkm->tunnels; j < pkm->tunnel_max; j++, fe++) { if (fe->ai.ai_addr && fe->fe_hostname && (fe->conn.sockfd >= 0)) { if (fe->conn.status & FE_STATUS_WANTED) { if (NULL != in_ipaddr_to_str(fe->ai.ai_addr, printip, 128)) { len = strlen(printip); if (len < 1000-(alp-address_list)) { if (alp != address_list) *alp++ = ','; strcpy(alp, printip); alp += len; *fes++ = fe; *fes = NULL; } } if (!(fe->conn.status & FE_STATUS_IN_DNS) || pk_state.force_update) bogus++; } else /* Stuff in DNS that shouldn't be also triggers updates */ if (fe->conn.status & FE_STATUS_IN_DNS) bogus++; } } PK_CHECK_MEMORY_CANARIES; if (!bogus) return 0; if (!address_list[0]) return 0; bogus = 0; lastup = ""; for (j = 0, kite = pkm->kites; j < pkm->kite_max; kite++, j++) { if ((kite->protocol[0] != '\0') && (0 != strcasecmp(lastup, kite->public_domain))) { PKS_STATE(pkm->status = PK_STATUS_UPDATING_DNS); sprintf(payload, "%s:%s", kite->public_domain, address_list); pk_sign(NULL, kite->auth_secret, payload, 100, signature); sprintf(url, pkm->dynamic_dns_url, kite->public_domain, address_list, signature); rlen = http_get(url, get_result, 10240); if (rlen < 1) { pk_log(PK_LOG_MANAGER_ERROR, "DDNS: No response from %s", url); bogus++; } else { lastup = kite->public_domain; result = skip_http_header(rlen, get_result); if ((strncasecmp(result, "nochg", 5) == 0) || (strncasecmp(result, "good", 4) == 0)) { pk_log(PK_LOG_MANAGER_INFO, "DDNS: Update OK, %s=%s", kite->public_domain, address_list); for (fes = fe_list; *fes; fes++) { (*fes)->last_ddnsup = time(0); (*fes)->conn.status |= FE_STATUS_IN_DNS; } } else { result[7] = '\0'; pk_log(PK_LOG_MANAGER_ERROR, "DDNS: Update failed for %s (%s -> %s)", kite->public_domain, url, result); bogus++; } } } } pkm->last_dns_update = time(0); PK_CHECK_MEMORY_CANARIES; return bogus; }
int main( int argc, char *argv[] ) { FILE *f; int ret = 1; pk_context pk; entropy_context entropy; ctr_drbg_context ctr_drbg; unsigned char hash[20]; unsigned char buf[POLARSSL_MPI_MAX_SIZE]; char filename[512]; const char *pers = "pk_sign"; size_t olen = 0; entropy_init( &entropy ); pk_init( &pk ); if( argc != 3 ) { polarssl_printf( "usage: pk_sign <key_file> <filename>\n" ); #if defined(_WIN32) polarssl_printf( "\n" ); #endif goto exit; } polarssl_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { polarssl_printf( " failed\n ! ctr_drbg_init returned -0x%04x\n", -ret ); goto exit; } polarssl_printf( "\n . Reading private key from '%s'", argv[1] ); fflush( stdout ); if( ( ret = pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 ) { ret = 1; polarssl_printf( " failed\n ! Could not open '%s'\n", argv[1] ); goto exit; } /* * Compute the SHA-1 hash of the input file, * then calculate the signature of the hash. */ polarssl_printf( "\n . Generating the SHA-1 signature" ); fflush( stdout ); if( ( ret = sha1_file( argv[2], hash ) ) != 0 ) { polarssl_printf( " failed\n ! Could not open or read %s\n\n", argv[2] ); goto exit; } if( ( ret = pk_sign( &pk, POLARSSL_MD_SHA1, hash, 0, buf, &olen, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! pk_sign returned -0x%04x\n", -ret ); goto exit; } /* * Write the signature into <filename>-sig.txt */ snprintf( filename, sizeof(filename), "%s.sig", argv[2] ); if( ( f = fopen( filename, "wb+" ) ) == NULL ) { ret = 1; polarssl_printf( " failed\n ! Could not create %s\n\n", filename ); goto exit; } if( fwrite( buf, 1, olen, f ) != olen ) { polarssl_printf( "failed\n ! fwrite failed\n\n" ); goto exit; } fclose( f ); polarssl_printf( "\n . Done (created \"%s\")\n\n", filename ); exit: pk_free( &pk ); ctr_drbg_free( &ctr_drbg ); entropy_free( &entropy ); #if defined(POLARSSL_ERROR_C) polarssl_strerror( ret, (char *) buf, sizeof(buf) ); polarssl_printf( " ! Last error was: %s\n", buf ); #endif #if defined(_WIN32) polarssl_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; const char *sig_oid; size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; unsigned char sig[POLARSSL_MPI_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; pk_type_t pk_alg; /* * Prepare data to be signed in tmp_buf */ c = tmp_buf + sizeof( tmp_buf ); ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); if( len ) { ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) ); ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ, OID_SIZE( OID_PKCS9_CSR_EXT_REQ ) ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); } ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ); ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->key, tmp_buf, c - tmp_buf ) ); c -= pub_len; len += pub_len; /* * Subject ::= Name */ ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) ); /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); /* * Prepare signature */ md( md_info_from_type( ctx->md_alg ), c, len, hash ); if( ( ret = pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, f_rng, p_rng ) ) != 0 ) { return( ret ); } if( pk_can_do( ctx->key, POLARSSL_PK_RSA ) ) pk_alg = POLARSSL_PK_RSA; else if( pk_can_do( ctx->key, POLARSSL_PK_ECDSA ) ) pk_alg = POLARSSL_PK_ECDSA; else return( POLARSSL_ERR_X509_INVALID_ALG ); if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, &sig_oid, &sig_oid_len ) ) != 0 ) { return( ret ); } /* * Write data to output buffer */ c2 = buf + size; ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf, sig_oid, sig_oid_len, sig, sig_len ) ); if( len > (size_t)( c2 - buf ) ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); c2 -= len; memcpy( c2, c, len ); len += sig_and_oid_len; ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); return( (int) len ); }
void attacker_send_asym_signature(havege_state *havege_state, void* socket) //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker); //@ ensures attacker_invariant(pub, pred, kc, havege_state, socket, attacker); { int temp; int size1; int size2; unsigned int osize; char buffer1[MAX_MESSAGE_SIZE]; char buffer2[MAX_MESSAGE_SIZE]; char buffer3[MAX_MESSAGE_SIZE]; pk_context context; //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker); size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE); size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE); if (size1 <= 0 || size2 < MINIMAL_STRING_SIZE) { //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); return; } //@ close pk_context(&context); pk_init(&context); //@ interpret_private_key(buffer1, size1); //@ assert cryptogram(buffer1, size1, ?ccs1, ?cg_key); //@ assert cg_key == cg_private_key(?p, ?c); if (pk_parse_key(&context, buffer1, (unsigned int) size1, NULL, 0) == 0) { if (size2 * 8 < size1) { //@ close random_state_predicate(havege_state_initialized); /*@ produce_function_pointer_chunk random_function( attacker_key_item_havege_random_stub) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ chars_to_crypto_chars(buffer2, size2); if (pk_sign(&context, POLARSSL_MD_NONE, buffer2, (unsigned int) size2, buffer3, &osize, attacker_key_item_havege_random_stub, havege_state) == 0) { /*@ { assert u_integer(&osize, ?osize_val); assert cryptogram(buffer3, osize_val, ?ccs_enc, ?cg_sig); assert cg_sig == cg_asym_signature(p, c, ?cs2, _); assert is_public_asym_signature_is_public(?proof, pub, pred); crypto_chars_to_chars(buffer2, size2); public_chars(buffer2, size2); proof(cg_sig); public_cryptogram(buffer3, cg_sig); chars_to_crypto_chars(buffer2, size2); } @*/ net_send(socket, buffer3, osize); } //@ crypto_chars_to_chars(buffer2, size2); } //@ pk_release_context_with_key(&context); } pk_free(&context); //@ open pk_context(&context); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); //@ public_cryptogram(buffer1, cg_key); }
int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; const char *sig_oid; size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; unsigned char sig[POLARSSL_MPI_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; pk_type_t pk_alg; /* * Prepare data to be signed in tmp_buf */ c = tmp_buf + sizeof( tmp_buf ); /* Signature algorithm needed in TBS, and later for actual signature */ pk_alg = pk_get_type( ctx->issuer_key ); if( pk_alg == POLARSSL_PK_ECKEY ) pk_alg = POLARSSL_PK_ECDSA; if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, &sig_oid, &sig_oid_len ) ) != 0 ) { return( ret ); } /* * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension */ ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ); /* * SubjectPublicKeyInfo */ ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->subject_key, tmp_buf, c - tmp_buf ) ); c -= pub_len; len += pub_len; /* * Subject ::= Name */ ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) ); /* * Validity ::= SEQUENCE { * notBefore Time, * notAfter Time } */ sub_len = 0; ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after, X509_RFC5280_UTC_TIME_LEN ) ); ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before, X509_RFC5280_UTC_TIME_LEN ) ); len += sub_len; ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); /* * Issuer ::= Name */ ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->issuer ) ); /* * Signature ::= AlgorithmIdentifier */ ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf, sig_oid, strlen( sig_oid ), 0 ) ); /* * Serial ::= INTEGER */ ASN1_CHK_ADD( len, asn1_write_mpi( &c, tmp_buf, &ctx->serial ) ); /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ sub_len = 0; ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) ); len += sub_len; ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); /* * Make signature */ md( md_info_from_type( ctx->md_alg ), c, len, hash ); if( ( ret = pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, f_rng, p_rng ) ) != 0 ) { return( ret ); } /* * Write data to output buffer */ c2 = buf + size; ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf, sig_oid, sig_oid_len, sig, sig_len ) ); c2 -= len; memcpy( c2, c, len ); len += sig_and_oid_len; ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); return( (int) len ); }
struct item *asymmetric_signature(struct item *key, struct item *payload) /*@ requires [?f]world(?pub, ?key_clsfy) &*& principal(?principal1, ?count1) &*& item(payload, ?pay, pub) &*& item(key, ?k, pub) &*& k == private_key_item(?principal2, ?count2); @*/ /*@ ensures [f]world(pub, key_clsfy) &*& principal(principal1, count1 + 1) &*& item(payload, pay, pub) &*& item(key, k, pub) &*& item(result, ?sig, pub) &*& col ? true : sig == asymmetric_signature_item(principal2, count2, some(pay), ?ent); @*/ { debug_print("ASYM SIGNING:\n"); print_item(payload); struct item* result; result = malloc(sizeof(struct item)); if (result == 0) abort_crypto_lib("Malloc failed"); debug_print("signing item\n"); print_item(payload); print_item(key); { pk_context context; unsigned int olen; char* output; // Key //@ close pk_context(&context); //@ open [f]world(pub, key_clsfy); pk_init(&context); //@ close [f]world(pub, key_clsfy); set_private_key(&context, key); //@ open [f]world(pub, key_clsfy); /*@ assert pk_context_with_key(&context, pk_private, ?principal, ?count, RSA_BIT_KEY_SIZE); @*/ //@ assert col || principal == principal2; //@ assert col || count == count2; // Payload //@ open item(payload, pay, pub); //@ open [_]item_constraints(pay, ?pay_cs, pub); //@ assert payload->content |-> ?p_cont &*& payload->size |-> ?p_size; if (payload->size > RSA_KEY_SIZE) abort_crypto_lib("Assymetric signing failed: incorrect size"); output = malloc(RSA_KEY_SIZE); if (output == 0) abort_crypto_lib("Malloc failed"); void *random_state = nonces_expose_state(); //@ close random_state_predicate(havege_state_initialized); /*@ produce_function_pointer_chunk random_function( asym_sig_havege_random_stub) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ open principal(principal1, count1); if(pk_sign(&context, POLARSSL_MD_NONE, payload->content, (unsigned int) payload->size, output, &olen, asym_sig_havege_random_stub, random_state) != 0) abort_crypto_lib("Signing failed"); //@ open principal(principal1, count1 + 1); //@ open cryptogram(output, ?sig_length, ?sig_cs, ?sig_cg); //@ assert sig_cg == cg_asym_signature(principal, count, pay_cs, ?ent); //@ assert u_integer(&olen, sig_length); //@ assert sig_length > 0 &*& sig_length <= RSA_KEY_SIZE; nonces_hide_state(random_state); //@ pk_release_context_with_key(&context); pk_free(&context); //@ open pk_context(&context); //@ close [f]world(pub, key_clsfy); debug_print("signed item\n"); print_buffer(output, (int) olen); // Create item if (olen < MINIMAL_STRING_SIZE) abort_crypto_lib("Assymetric signing failed: output to small"); result->size = TAG_LENGTH + (int) olen; result->content = malloc(result->size); if (result->content == 0) {abort_crypto_lib("Malloc failed");} write_tag(result->content, TAG_ASYMMETRIC_SIG); //@ assert result->content |-> ?cont &*& result->size |-> ?size; //@ assert chars(cont, TAG_LENGTH, ?tag_cs); //@ assert tag_cs == full_tag(TAG_ASYMMETRIC_SIG); //@ public_chars(cont, TAG_LENGTH); //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH); memcpy(result->content + TAG_LENGTH, output, olen); //@ crypto_chars_join(cont); //@ list<char> cs = append(tag_cs, sig_cs); //@ assert crypto_chars(secret, cont, size, cs); //@ item e = asymmetric_signature_item(principal, count, some(pay), ent); //@ close ic_cg(e)(sig_cs, sig_cg); /*@ if (col) { public_chars(cont, size); public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH); } @*/ //@ close item(payload, pay, pub); zeroize(output, (int) olen); //@ chars_join(output); free(output); //@ WELL_FORMED(tag_cs, sig_cs, TAG_ASYMMETRIC_SIG) //@ close ic_parts(e)(tag_cs, sig_cs); //@ close well_formed_item_chars(e)(pay_cs); //@ leak well_formed_item_chars(e)(pay_cs); //@ close item_constraints(e, cs, pub); //@ leak item_constraints(e, cs, pub); //@ close item(result, e, pub); } debug_print("SINGING RESULT:\n"); print_item(result); return result; }