void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) { switch(ctx->mac_type){ case SSH_MAC_SHA1: sha1_final(md,ctx->ctx.sha1_ctx); break; case SSH_MAC_SHA256: sha256_final(md,ctx->ctx.sha256_ctx); break; case SSH_MAC_SHA384: case SSH_MAC_SHA512: default: break; } SAFE_FREE(ctx); }
char * ap_keying_material_pubkey_derivate(apr_pool_t *p, const char *key, const char *pub) { sha1_context sha1; sha1_init(&sha1); sha1_update(&sha1, (byte *)key, strlen(key)); sha1_update(&sha1, (byte *)pub, strlen(pub)); char *hash = (char *)sha1_final(&sha1); char *sec = apr_palloc(p, SHA1_HEX_SIZE); mem_to_hex(sec, hash, SHA1_SIZE, 0); return sec; }
ssh_string SshAgentSignRsaSha1(uint8_t* data, int dataSize, ssh_key key, uint32_t flags) { // Compute the hash. unsigned char hash[SHA_DIGEST_LEN] = {0}; SHACTX ctx; ctx = sha1_init(); if (ctx == NULL) { return NULL; } sha1_update(ctx, data, dataSize); sha1_final(hash, ctx); // This release ctx. // Prepare the buffer to hold the signature in a blob of the form: // signatureBlobLength[ signatureTypeLength[ signatureType ] signatureLength[ signature ] ] int signatureTypeLength = 7; int signatureLength = RSA_size(key->rsa); int signatureBlobLength = 8 + signatureTypeLength + signatureLength; uint8_t* signatureBlob = malloc(4 + signatureBlobLength); if (signatureBlob == NULL) { return NULL; } pack32(signatureBlob, signatureBlobLength); int index = 4; pack32(signatureBlob + index, signatureTypeLength); index += 4; memcpy(signatureBlob + index, "ssh-rsa", signatureTypeLength); index += signatureTypeLength; pack32(signatureBlob + 15, signatureLength); index += 4; // Sign the hash in place in the signature blob buffer. unsigned int len; int result = RSA_sign(NID_sha1, hash, sizeof(hash), signatureBlob + index, &len, key->rsa); if (result != 1) { free(signatureBlob); return NULL; } return (ssh_string)signatureBlob; }
/* * This function signs the session id (known as H) as a string then * the content of sigbuf */ ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, ssh_key privatekey) { struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; ssh_string session_str = NULL; ssh_string signature = NULL; struct signature_struct *sign = NULL; SHACTX ctx = NULL; if (privatekey == NULL || !ssh_key_is_private(privatekey)) { return NULL; } session_str = ssh_string_new(SHA_DIGEST_LEN); if (session_str == NULL) { return NULL; } ssh_string_fill(session_str, crypto->session_id, SHA_DIGEST_LEN); ctx = sha1_init(); if (ctx == NULL) { ssh_string_free(session_str); return NULL; } sha1_update(ctx, session_str, ssh_string_len(session_str) + 4); ssh_string_free(session_str); sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); sha1_final(hash + 1,ctx); hash[0] = 0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN); #endif sign = pki_do_sign(privatekey, hash); if (sign == NULL) { return NULL; } signature = signature_to_string(sign); signature_free(sign); return signature; }
static int decode_message(int type, uint8_t *msg, size_t msg_len, uint8_t *data, size_t *data_len) { size_t i; sha1_ctx_t ctx; /* decode message according to type */ switch (type) { case RSA_ES_PKCSV15: /* EM = 0x00||0x02||nonzero random-pad||0x00||data */ if (msg_len < 11) return -1; if (msg[0] != 0x00 || msg[1] != 0x02) return -1; for (i = 2; i < msg_len && msg[i]; i++); if (i < 10 || i >= msg_len) return -1; *data_len = msg_len - i - 1; memmove(data, &msg[i + 1], *data_len); break; case RSA_ES_OAEP_SHA1: /* DB = SHA-1("TCPA")||0x00-pad||0x01||data seed = random value of size SHA1_DIGEST_LENGTH masked-seed = seed xor MFG(seed, seed_len) masked-DB = DB xor MFG(seed, DB_len) EM = 0x00||masked-seed||masked-DB */ if (msg_len < 2 + 2 * SHA1_DIGEST_LENGTH) return -1; if (msg[0] != 0x00) return -1; mask_generation(&msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1, &msg[1], SHA1_DIGEST_LENGTH); mask_generation(&msg[1], SHA1_DIGEST_LENGTH, &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1); sha1_init(&ctx); sha1_update(&ctx, (uint8_t *) "TCPA", 4); sha1_final(&ctx, &msg[1]); if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], SHA1_DIGEST_LENGTH) != 0) return -1; for (i = 1 + 2 * SHA1_DIGEST_LENGTH; i < msg_len && !msg[i]; i++); if (i >= msg_len || msg[i] != 0x01) return -1; *data_len = msg_len - i - 1; memmove(data, &msg[i + 1], *data_len); break; default: /* unsupported encoding method */ return -1; } return 0; }
void mask_generation(uint8_t *seed, size_t seed_len, uint8_t *data, size_t data_len) { sha1_ctx_t ctx; uint8_t mask[SHA1_DIGEST_LENGTH]; uint32_t i, len, counter = 0; while (data_len > 0) { sha1_init(&ctx); sha1_update(&ctx, seed, seed_len); sha1_update(&ctx, (uint8_t*)&counter, 4); sha1_final(&ctx, mask); counter = CPU_TO_BE32(BE32_TO_CPU(counter) + 1); len = (data_len < SHA1_DIGEST_LENGTH) ? data_len : SHA1_DIGEST_LENGTH; for (i = 0; i < len; i++) *data++ ^= mask[i]; data_len -= len; } }
int test5(void) { SHA1 sha1; uint8_t digest[SHA1_DIGEST_LENGTH]; uint8_t expected_digest[SHA1_DIGEST_LENGTH] = { 0xDA, 0x39, 0xA3, 0xEE, 0x5E, 0x6B, 0x4B, 0x0D, 0x32, 0x55, 0xBF, 0xEF, 0x95, 0x60, 0x18, 0x90, 0xAF, 0xD8, 0x07, 0x09 }; sha1_init(&sha1); sha1_update(&sha1, (uint8_t *)"", 0); sha1_final(&sha1, digest); if (memcmp(digest, expected_digest, SHA1_DIGEST_LENGTH) != 0) { printf("test5: digest mismatch\n"); return -1; } return 0; }
int test1(void) { SHA1 sha1; uint8_t digest[SHA1_DIGEST_LENGTH]; uint8_t expected_digest[SHA1_DIGEST_LENGTH] = { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }; sha1_init(&sha1); sha1_update(&sha1, (uint8_t *)"abc", 3); sha1_final(&sha1, digest); if (memcmp(digest, expected_digest, SHA1_DIGEST_LENGTH) != 0) { printf("test1: digest mismatch\n"); return -1; } return 0; }
int test2(void) { SHA1 sha1; uint8_t digest[SHA1_DIGEST_LENGTH]; uint8_t expected_digest[SHA1_DIGEST_LENGTH] = { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }; sha1_init(&sha1); sha1_update(&sha1, (uint8_t *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56); sha1_final(&sha1, digest); if (memcmp(digest, expected_digest, SHA1_DIGEST_LENGTH) != 0) { printf("test2: digest mismatch\n"); return -1; } return 0; }
int test3(void) { SHA1 sha1; uint8_t digest[SHA1_DIGEST_LENGTH]; uint8_t expected_digest[SHA1_DIGEST_LENGTH] = { 0xA4, 0x9B, 0x24, 0x46, 0xA0, 0x2C, 0x64, 0x5B, 0xF4, 0x19, 0xF9, 0x95, 0xB6, 0x70, 0x91, 0x25, 0x3A, 0x04, 0xA2, 0x59 }; sha1_init(&sha1); sha1_update(&sha1, (uint8_t *)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112); sha1_final(&sha1, digest); if (memcmp(digest, expected_digest, SHA1_DIGEST_LENGTH) != 0) { printf("test3: digest mismatch\n"); return -1; } return 0; }
static int generate_one_key(ssh_string k, unsigned char session_id[SHA_DIGEST_LEN], unsigned char output[SHA_DIGEST_LEN], char letter) { SHACTX ctx = NULL; ctx = sha1_init(); if (ctx == NULL) { return -1; } sha1_update(ctx, k, ssh_string_len(k) + 4); sha1_update(ctx, session_id, SHA_DIGEST_LEN); sha1_update(ctx, &letter, 1); sha1_update(ctx, session_id, SHA_DIGEST_LEN); sha1_final(output, ctx); return 0; }
word32 prng_next(prng *p) { word32 tmp[HW]; byte buffer[(3 * HW + 2) * 4]; word32 i, j; sha1_ctx c; p->seed[0] += 1; for (i = 0; i < p->count; i += 1) { for (j = 0; j < 4; j += 1) { buffer[i * 4 + j] = (byte)(p->seed[i] >> (j * 8)); } } sha1_initial(&c); sha1_process(&c, buffer, p->count * 4); sha1_final(&c, tmp); memset(buffer, 0, sizeof(buffer)); return tmp[0]; }
static int vfs_randomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf) { sha1_decl(shactx); uint8_t d[20]; int w; while(nBuf > 0) { sha1_init(shactx); sha1_update(shactx, (void *)&random_seed, sizeof(uint64_t)); sha1_final(shactx, d); w = MIN(20, nBuf); memcpy(zBuf, d, w); nBuf -= w; zBuf += w; memcpy(&random_seed, d, sizeof(uint64_t)); } return SQLITE_OK; }
/* Create a (unique?) sha1 based on content of the file */ bool DirectoryWorker::sha1Compute(QString filename, unsigned char *sha1) { FILE *fd; quint64 fsize; unsigned int rsize = 0; quint8 *tmp; SHA1 ctx; fd = fopen(filename.toUtf8().data(), "rb"); if (!fd) { qDebug() << "Error opening " << filename; return false; } if (!sha1) return false; sha1_init(&ctx); fseek(fd, 0, SEEK_END); fsize = ftell(fd); fseek(fd, 0, SEEK_SET); rsize = MIN(65536, fsize); tmp = (quint8*)calloc(rsize, sizeof(uint8_t)); fread(tmp, 1, rsize, fd); sha1_update(&ctx, tmp, rsize); fseek(fd, (long)(fsize - 65536), SEEK_SET); fread(tmp, 1, rsize, fd); sha1_update(&ctx, tmp, rsize); sha1_final(&ctx, sha1); free(tmp); fclose(fd); return true; }
int test4(void) { SHA1 sha1; int i; uint8_t digest[SHA1_DIGEST_LENGTH]; uint8_t expected_digest[SHA1_DIGEST_LENGTH] = { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }; sha1_init(&sha1); for (i = 0; i < 1000000; ++i) { sha1_update(&sha1, (uint8_t *)"a", 1); } sha1_final(&sha1, digest); if (memcmp(digest, expected_digest, SHA1_DIGEST_LENGTH) != 0) { printf("test4: digest mismatch\n"); return -1; } return 0; }
int test6(void) { SHA1 sha1; int i; uint8_t digest[SHA1_DIGEST_LENGTH]; uint8_t expected_digest[SHA1_DIGEST_LENGTH] = { 0x77, 0x89, 0xF0, 0xC9, 0xEF, 0x7B, 0xFC, 0x40, 0xD9, 0x33, 0x11, 0x14, 0x3D, 0xFB, 0xE6, 0x9E, 0x20, 0x17, 0xF5, 0x92 }; sha1_init(&sha1); for (i = 0; i < 16777216; ++i) { sha1_update(&sha1, (uint8_t *)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno", 64); } sha1_final(&sha1, digest); if (memcmp(digest, expected_digest, SHA1_DIGEST_LENGTH) != 0) { printf("test6: digest mismatch\n"); return -1; } return 0; }
int generate_session_keys(ssh_session session) { ssh_string k_string = NULL; SHACTX ctx = NULL; int rc = -1; enter_function(); k_string = make_bignum_string(session->next_crypto->k); if (k_string == NULL) { goto error; } /* IV */ if (session->client) { if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->encryptIV, 'A') < 0) { goto error; } if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->decryptIV, 'B') < 0) { goto error; } } else { if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->decryptIV, 'A') < 0) { goto error; } if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->encryptIV, 'B') < 0) { goto error; } } if (session->client) { if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->encryptkey, 'C') < 0) { goto error; } if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->decryptkey, 'D') < 0) { goto error; } } else { if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->decryptkey, 'C') < 0) { goto error; } if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->encryptkey, 'D') < 0) { goto error; } } /* some ciphers need more than 20 bytes of input key */ /* XXX verify it's ok for server implementation */ if (session->next_crypto->out_cipher->keysize > SHA_DIGEST_LEN * 8) { ctx = sha1_init(); if (ctx == NULL) { goto error; } sha1_update(ctx, k_string, ssh_string_len(k_string) + 4); sha1_update(ctx, session->next_crypto->session_id, SHA_DIGEST_LEN); sha1_update(ctx, session->next_crypto->encryptkey, SHA_DIGEST_LEN); sha1_final(session->next_crypto->encryptkey + SHA_DIGEST_LEN, ctx); } if (session->next_crypto->in_cipher->keysize > SHA_DIGEST_LEN * 8) { ctx = sha1_init(); sha1_update(ctx, k_string, ssh_string_len(k_string) + 4); sha1_update(ctx, session->next_crypto->session_id, SHA_DIGEST_LEN); sha1_update(ctx, session->next_crypto->decryptkey, SHA_DIGEST_LEN); sha1_final(session->next_crypto->decryptkey + SHA_DIGEST_LEN, ctx); } if(session->client) { if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->encryptMAC, 'E') < 0) { goto error; } if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->decryptMAC, 'F') < 0) { goto error; } } else { if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->decryptMAC, 'E') < 0) { goto error; } if (generate_one_key(k_string, session->next_crypto->session_id, session->next_crypto->encryptMAC, 'F') < 0) { goto error; } } #ifdef DEBUG_CRYPTO ssh_print_hexa("Encrypt IV", session->next_crypto->encryptIV, SHA_DIGEST_LEN); ssh_print_hexa("Decrypt IV", session->next_crypto->decryptIV, SHA_DIGEST_LEN); ssh_print_hexa("Encryption key", session->next_crypto->encryptkey, session->next_crypto->out_cipher->keysize); ssh_print_hexa("Decryption key", session->next_crypto->decryptkey, session->next_crypto->in_cipher->keysize); ssh_print_hexa("Encryption MAC", session->next_crypto->encryptMAC, SHA_DIGEST_LEN); ssh_print_hexa("Decryption MAC", session->next_crypto->decryptMAC, 20); #endif rc = 0; error: ssh_string_free(k_string); leave_function(); return rc; }
int compute_OTP (char * secret_hex, long long int counter) { SHA1_INFO ctx; uint8_t sha1[SHA1_DIGEST_LENGTH]; uint8_t sha2[SHA1_DIGEST_LENGTH]; sha1_init (&ctx); //edit: lab handout probably had a typo @pad with leading zeroes uint8_t pad[21] = {0}; memset (pad, '0', 20); int i; for (i = 0; i < strlen(secret_hex); ++i) { pad[i] = secret_hex[i]; } //binary value of secret char * pos = pad; uint8_t c[8]; uint8_t val[10] = {0}; for (i = 0; i < 10; i++){ sscanf(pos, "%2hhx", &val[i]); pos += 2; } /* for (int i = 0; i < 10; ++i) { printf("%x ", val[i]); }*/ uint8_t val_ipad[64]; uint8_t val_opad[64]; memset( val_ipad, 0, sizeof(val_ipad)); memset( val_opad, 0, sizeof(val_opad)); memcpy( val_ipad, val, 10); memcpy( val_opad, val, 10); for (i = 0; i < 64; ++i) { val_ipad[i] = val_ipad[i] ^ 0x36; val_opad[i] = val_opad[i] ^ 0x5c; } //binary value of counter, 64 bits for (i=7; i>=0; i--) { c[i] = (uint8_t) counter & 0xff; counter = counter >> 8; } sha1_update (&ctx, val_ipad, 64); sha1_update (&ctx, c, 8); //sha1_update (&ctx, total_i, 18); sha1_final (&ctx, sha1); sha1_init (&ctx); sha1_update(&ctx, val_opad, 64); sha1_update(&ctx, sha1, SHA1_DIGEST_LENGTH); sha1_final(&ctx, sha2); int offset = sha2[SHA1_DIGEST_LENGTH-1] & 0xf; int binary = ((sha2[offset] & 0x7f) << 24) | ((sha2[offset+1] & 0xff) << 16) | ((sha2[offset+2] & 0xff) << 8) | ((sha2[offset+3] & 0xff)); int otp = binary % 1000000; return otp; }
static int encode_message(int type, uint8_t *data, size_t data_len, uint8_t *msg, size_t msg_len) { size_t i; sha1_ctx_t ctx; /* encode message according to type */ switch (type) { case RSA_SSA_PKCS1_SHA1: /* EM = 0x00||0x01||0xff-pad||0x00||SHA-1 DER header||SHA-1 digest */ if (msg_len < 35 + 11) return -1; msg[0] = 0x00; msg[1] = 0x01; memset(&msg[2], 0xff, msg_len - 38); msg[msg_len - 36] = 0x00; memcpy(&msg[msg_len - 35], "\x30\x21\x30\x09\x06\x05\x2b" "\x0e\x03\x02\x1a\x05\x00\x04\x14", 15); sha1_init(&ctx); sha1_update(&ctx, data, data_len); sha1_final(&ctx, &msg[msg_len - 20]); break; case RSA_SSA_PKCS1_SHA1_RAW: /* EM = 0x00||0x01||0xff-pad||0x00||SHA-1 DER header||SHA-1 digest */ if (msg_len < 35 + 11 || data_len != 20) return -1; msg[0] = 0x00; msg[1] = 0x01; memset(&msg[2], 0xff, msg_len - 38); msg[msg_len - 36] = 0x00; memcpy(&msg[msg_len - 35], "\x30\x21\x30\x09\x06\x05\x2b" "\x0e\x03\x02\x1a\x05\x00\x04\x14", 15); memcpy(&msg[msg_len - 20], data, data_len); break; case RSA_SSA_PKCS1_DER: /* EM = 0x00||0x01||0xff-pad||0x00||DER encoded data */ if (msg_len < data_len + 11) return -1; msg[0] = 0x00; msg[1] = 0x01; memset(&msg[2], 0xff, msg_len - data_len - 3); msg[msg_len - data_len - 1] = 0x00; memcpy(&msg[msg_len - data_len], data, data_len); break; case RSA_ES_PKCSV15: /* EM = 0x00||0x02||nonzero random-pad||0x00||data */ if (msg_len < data_len + 11) return -1; msg[0] = 0x00; msg[1] = 0x02; tpm_get_random_bytes(&msg[2], msg_len - data_len - 3); for (i = 2; i < msg_len - data_len; i++) while (!msg[i]) get_random_bytes(&msg[i], 1); msg[msg_len - data_len - 1] = 0x00; memcpy(&msg[msg_len - data_len], data, data_len); break; case RSA_ES_OAEP_SHA1: /* DB = SHA-1("TCPA")||0x00-pad||0x01||data seed = random value of size SHA1_DIGEST_LENGTH masked-seed = seed xor MFG(seed, seed_len) masked-DB = DB xor MFG(seed, DB_len) EM = 0x00||masked-seed||masked-DB */ if (msg_len < data_len + 2 * SHA1_DIGEST_LENGTH + 2) return -1; msg[0] = 0x00; get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH); sha1_init(&ctx); sha1_update(&ctx, (uint8_t *) "TCPA", 4); sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]); memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2); msg[msg_len - data_len - 1] = 0x01; memcpy(&msg[msg_len - data_len], data, data_len); mask_generation(&msg[1], SHA1_DIGEST_LENGTH, &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1); mask_generation(&msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1, &msg[1], SHA1_DIGEST_LENGTH); break; default: /* unsupported encoding method */ return -1; } return 0; }
/** * @brief Allocates a buffer with the hash of the public key. * * This function allows you to get a hash of the public key. You can then * print this hash in a human-readable form to the user so that he is able to * verify it. Use ssh_get_hexa() or ssh_print_hexa() to display it. * * @param[in] key The public key to create the hash for. * * @param[in] type The type of the hash you want. * * @param[in] hash A pointer to store the allocated buffer. It can be * freed using ssh_clean_pubkey_hash(). * * @param[in] hlen The length of the hash. * * @return 0 on success, -1 if an error occured. * * @warning It is very important that you verify at some moment that the hash * matches a known server. If you don't do it, cryptography wont help * you at making things secure. * OpenSSH uses SHA1 to print public key digests. * * @see ssh_is_server_known() * @see ssh_get_hexa() * @see ssh_print_hexa() * @see ssh_clean_pubkey_hash() */ int ssh_get_publickey_hash(const ssh_key key, enum ssh_publickey_hash_type type, unsigned char **hash, size_t *hlen) { ssh_string blob; unsigned char *h; int rc; rc = ssh_pki_export_pubkey_blob(key, &blob); if (rc < 0) { return rc; } switch (type) { case SSH_PUBLICKEY_HASH_SHA1: { SHACTX ctx; h = malloc(SHA_DIGEST_LEN); if (h == NULL) { rc = -1; goto out; } ctx = sha1_init(); if (ctx == NULL) { free(h); rc = -1; goto out; } sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); sha1_final(h, ctx); *hlen = SHA_DIGEST_LEN; } break; case SSH_PUBLICKEY_HASH_MD5: { MD5CTX ctx; h = malloc(MD5_DIGEST_LEN); if (h == NULL) { rc = -1; goto out; } ctx = md5_init(); if (ctx == NULL) { free(h); rc = -1; goto out; } md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); md5_final(h, ctx); *hlen = MD5_DIGEST_LEN; } break; default: rc = -1; goto out; } *hash = h; rc = 0; out: ssh_string_free(blob); return rc; }
int make_sessionid(ssh_session session) { SHACTX ctx; ssh_string num = NULL; ssh_string str = NULL; ssh_buffer server_hash = NULL; ssh_buffer client_hash = NULL; ssh_buffer buf = NULL; uint32_t len; int rc = SSH_ERROR; enter_function(); ctx = sha1_init(); if (ctx == NULL) { return rc; } buf = ssh_buffer_new(); if (buf == NULL) { return rc; } str = ssh_string_from_char(session->clientbanner); if (str == NULL) { goto error; } if (buffer_add_ssh_string(buf, str) < 0) { goto error; } ssh_string_free(str); str = ssh_string_from_char(session->serverbanner); if (str == NULL) { goto error; } if (buffer_add_ssh_string(buf, str) < 0) { goto error; } if (session->client) { server_hash = session->in_hashbuf; client_hash = session->out_hashbuf; } else { server_hash = session->out_hashbuf; client_hash = session->in_hashbuf; } if (buffer_add_u32(server_hash, 0) < 0) { goto error; } if (buffer_add_u8(server_hash, 0) < 0) { goto error; } if (buffer_add_u32(client_hash, 0) < 0) { goto error; } if (buffer_add_u8(client_hash, 0) < 0) { goto error; } len = ntohl(buffer_get_rest_len(client_hash)); if (buffer_add_u32(buf,len) < 0) { goto error; } if (buffer_add_data(buf, buffer_get_rest(client_hash), buffer_get_rest_len(client_hash)) < 0) { goto error; } len = ntohl(buffer_get_rest_len(server_hash)); if (buffer_add_u32(buf, len) < 0) { goto error; } if (buffer_add_data(buf, buffer_get_rest(server_hash), buffer_get_rest_len(server_hash)) < 0) { goto error; } len = ssh_string_len(session->next_crypto->server_pubkey) + 4; if (buffer_add_data(buf, session->next_crypto->server_pubkey, len) < 0) { goto error; } num = make_bignum_string(session->next_crypto->e); if (num == NULL) { goto error; } len = ssh_string_len(num) + 4; if (buffer_add_data(buf, num, len) < 0) { goto error; } ssh_string_free(num); num = make_bignum_string(session->next_crypto->f); if (num == NULL) { goto error; } len = ssh_string_len(num) + 4; if (buffer_add_data(buf, num, len) < 0) { goto error; } ssh_string_free(num); num = make_bignum_string(session->next_crypto->k); if (num == NULL) { goto error; } len = ssh_string_len(num) + 4; if (buffer_add_data(buf, num, len) < 0) { goto error; } #ifdef DEBUG_CRYPTO ssh_print_hexa("hash buffer", ssh_buffer_get_begin(buf), ssh_buffer_get_len(buf)); #endif sha1_update(ctx, buffer_get_rest(buf), buffer_get_rest_len(buf)); sha1_final(session->next_crypto->session_id, ctx); #ifdef DEBUG_CRYPTO printf("Session hash: "); ssh_print_hexa("session id", session->next_crypto->session_id, SHA_DIGEST_LEN); #endif rc = SSH_OK; error: ssh_buffer_free(buf); ssh_buffer_free(client_hash); ssh_buffer_free(server_hash); session->in_hashbuf = NULL; session->out_hashbuf = NULL; ssh_string_free(str); ssh_string_free(num); leave_function(); return rc; }
int door_main(void) { serial_init(9600, 8e2); pin_mode_output(PIN_RFID_ENABLE); pin_mode_input(PIN_CLK); /* clk */ pin_mode_input(PIN_DATA); /* data */ pin_mode_output(PIN_GREEN_LED); /* green led lock */ pin_mode_output(PIN_YELLOW_LED); /* yellow led lock */ pin_mode_output(PIN_OPEN_LOCK); /* open */ pin_mode_output(PIN_DAYMODE); /* stay open */ pin_mode_output(PIN_STATUS_LED); /* yellow status */ pin_high(PIN_OPEN_LOCK); pin_high(PIN_DAYMODE); pin_high(PIN_GREEN_LED); pin_high(PIN_YELLOW_LED); /* trigger pin2 interrupt when the clock * signal goes high */ pin2_interrupt_mode_rising(); pin2_interrupt_enable(); data_reset(); /* setup timer1 to trigger interrupt a 4 times a second */ timer1_mode_ctc(); timer1_compare_a_set(62499); timer1_clock_d64(); timer1_interrupt_a_enable(); softserial_init(); pin_mode_output(PIN_RFID_ENABLE); pin_low(PIN_RFID_ENABLE); init_mfrc522(); sleep_mode_idle(); while (1) { /* * sleep if no new events need to be handled * while avoiding race conditions. see * http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html */ cli(); if (events == EV_NONE && !ev_softserial) { sleep_enable(); sei(); sleep_cpu(); sleep_disable(); continue; } sei(); if (events & EV_SERIAL) { handle_serial_input(); continue; } if (ev_softserial) { handle_rfid_input(); } events &= ~EV_DATA; if (cnt > 0 && data[cnt - 1] == 0xB4) { if (cnt >= 10) { struct sha1_context ctx; char digest[SHA1_DIGEST_LENGTH]; sha1_init(&ctx); sha1_update(&ctx, (char *)data, 256); sha1_final(&ctx, digest); serial_print("HASH+"); serial_hexdump(digest, SHA1_DIGEST_LENGTH); serial_print("\n"); } data_reset(); continue; } if (events & EV_TIME) { char buf[20]; uint8_t len; len = check_mfrc522(buf, sizeof(buf)); handle_mfr_input(buf, len); } events &= ~EV_TIME; /* This code can be used during development, to simulate the press of the '#' button 8 seconds after every idle timeout: if (second == 32 && cnt < 255) { data[cnt] = 0xB4; cnt++; events |= EV_DATA; } */ if (second > 10*4) { serial_print("ALIVE\n"); second = 0; data_reset(); continue; } } }
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, const ssh_key privkey) { struct ssh_crypto_struct *crypto; ssh_signature sig = NULL; ssh_string sig_blob; int rc; if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) { return NULL; } crypto = session->next_crypto ? session->next_crypto : session->current_crypto; if (crypto->secret_hash == NULL){ ssh_set_error(session,SSH_FATAL,"Missing secret_hash"); return NULL; } if (privkey->type == SSH_KEYTYPE_ECDSA) { #ifdef HAVE_ECC unsigned char ehash[EVP_DIGEST_LEN] = {0}; uint32_t elen; evp(privkey->ecdsa_nid, crypto->secret_hash, crypto->digest_len, ehash, &elen); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", ehash, elen); #endif sig = pki_do_sign_sessionid(privkey, ehash, elen); if (sig == NULL) { return NULL; } #endif } else if (privkey->type == SSH_KEYTYPE_ED25519) { sig = ssh_signature_new(); if (sig == NULL){ return NULL; } sig->type = privkey->type; sig->type_c = privkey->type_c; rc = pki_ed25519_sign(privkey, sig, crypto->secret_hash, crypto->digest_len); if (rc != SSH_OK){ ssh_signature_free(sig); sig = NULL; } } else { unsigned char hash[SHA_DIGEST_LEN] = {0}; SHACTX ctx; ctx = sha1_init(); if (ctx == NULL) { return NULL; } sha1_update(ctx, crypto->secret_hash, crypto->digest_len); sha1_final(hash, ctx); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); #endif sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN); if (sig == NULL) { return NULL; } } rc = ssh_pki_export_signature_blob(sig, &sig_blob); ssh_signature_free(sig); if (rc < 0) { return NULL; } return sig_blob; }
static htsmsg_t * htsp_reqreply(htsp_connection_t *hc, htsmsg_t *m) { void *buf; size_t len; uint32_t seq; int r; tcpcon_t *tc = hc->hc_tc; uint32_t noaccess; htsmsg_t *reply; htsp_msg_t *hm = NULL; int retry = 0; char id[100]; char *username; char *password; sha1_decl(shactx); uint8_t d[20]; if(tc == NULL) return NULL; /* Generate a sequence number for our message */ seq = atomic_add(&hc->hc_seq_generator, 1); htsmsg_add_u32(m, "seq", seq); again: snprintf(id, sizeof(id), "htsp://%s:%d", hc->hc_hostname, hc->hc_port); r = keyring_lookup(id, &username, &password, NULL, NULL, "TV client", "Access denied", (retry ? KEYRING_QUERY_USER : 0) | KEYRING_SHOW_REMEMBER_ME | KEYRING_REMEMBER_ME_SET); if(r == -1) { /* User rejected */ return NULL; } if(r == 0) { /* Got auth credentials */ htsmsg_delete_field(m, "username"); htsmsg_delete_field(m, "digest"); if(username != NULL) htsmsg_add_str(m, "username", username); if(password != NULL) { sha1_init(shactx); sha1_update(shactx, (const uint8_t *)password, strlen(password)); sha1_update(shactx, hc->hc_challenge, 32); sha1_final(shactx, d); htsmsg_add_bin(m, "digest", d, 20); } free(username); free(password); } if(htsmsg_binary_serialize(m, &buf, &len, -1) < 0) { htsmsg_destroy(m); return NULL; } if(hc->hc_is_async) { /* Async, set up a struct that will be signalled when we get a reply */ hm = malloc(sizeof(htsp_msg_t)); hm->hm_msg = NULL; hm->hm_seq = seq; hm->hm_error = 0; hts_mutex_lock(&hc->hc_rpc_mutex); TAILQ_INSERT_TAIL(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); } if(tc->write(tc, buf, len)) { free(buf); htsmsg_destroy(m); if(hm != NULL) { hts_mutex_lock(&hc->hc_rpc_mutex); TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); free(hm); } return NULL; } free(buf); if(hm != NULL) { hts_mutex_lock(&hc->hc_rpc_mutex); while(1) { if(hm->hm_error != 0) { r = hm->hm_error; TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); free(hm); htsmsg_destroy(m); return NULL; } if(hm->hm_msg != NULL) break; hts_cond_wait(&hc->hc_rpc_cond, &hc->hc_rpc_mutex); } TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); reply = hm->hm_msg; free(hm); } else { if((reply = htsp_recv(hc)) == NULL) { htsmsg_destroy(m); return NULL; } } if(!htsmsg_get_u32(reply, "noaccess", &noaccess) && noaccess) { retry++; goto again; } htsmsg_destroy(m); /* Destroy original message */ return reply; }
/* * This function signs the session id as a string then * the content of sigbuf */ ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, const ssh_key privkey) { struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; ssh_signature sig = NULL; ssh_string sig_blob; ssh_string session_id; int rc; if (privkey == NULL || !ssh_key_is_private(privkey)) { return NULL; } session_id = ssh_string_new(crypto->digest_len); if (session_id == NULL) { return NULL; } ssh_string_fill(session_id, crypto->session_id, crypto->digest_len); if (privkey->type == SSH_KEYTYPE_ECDSA) { #ifdef HAVE_ECC unsigned char ehash[EVP_DIGEST_LEN] = {0}; uint32_t elen; EVPCTX ctx; ctx = evp_init(privkey->ecdsa_nid); if (ctx == NULL) { ssh_string_free(session_id); return NULL; } evp_update(ctx, session_id, ssh_string_len(session_id) + 4); evp_update(ctx, ssh_buffer_get(sigbuf), ssh_buffer_get_len(sigbuf)); evp_final(ctx, ehash, &elen); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", ehash, elen); #endif sig = pki_do_sign(privkey, ehash, elen); #endif } else if (privkey->type == SSH_KEYTYPE_ED25519){ ssh_buffer buf; buf = ssh_buffer_new(); if (buf == NULL) { ssh_string_free(session_id); return NULL; } ssh_buffer_set_secure(buf); rc = ssh_buffer_pack(buf, "SP", session_id, ssh_buffer_get_len(sigbuf), ssh_buffer_get(sigbuf)); if (rc != SSH_OK) { ssh_string_free(session_id); ssh_buffer_free(buf); return NULL; } sig = pki_do_sign(privkey, ssh_buffer_get(buf), ssh_buffer_get_len(buf)); ssh_buffer_free(buf); } else { unsigned char hash[SHA_DIGEST_LEN] = {0}; SHACTX ctx; ctx = sha1_init(); if (ctx == NULL) { ssh_string_free(session_id); return NULL; } sha1_update(ctx, session_id, ssh_string_len(session_id) + 4); sha1_update(ctx, ssh_buffer_get(sigbuf), ssh_buffer_get_len(sigbuf)); sha1_final(hash, ctx); #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); #endif sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN); } ssh_string_free(session_id); if (sig == NULL) { return NULL; } rc = ssh_pki_export_signature_blob(sig, &sig_blob); ssh_signature_free(sig); if (rc < 0) { return NULL; } return sig_blob; }
void nidh (dckey *priv, dckey *pub, char *priv_id, char *pub_id, char *label) { rawpub rpub; rawpriv rpriv; int reserve; /* Let's name it that! */ /* step 0: check that the private and public keys are compatible, i.e., they use the same group parameters */ if ((-1 == get_rawpub (&rpub, pub)) || (-1 == get_rawpriv (&rpriv, priv))) { printf ("%s: trouble importing GMP values from ElGamal-like keys\n", getprogname ()); printf ("priv:\n%s\n", dcexport_priv (priv)); printf ("pub:\n%s\n", dcexport_pub (pub)); exit (-1); } else if (mpz_cmp (rpub.p, rpriv.p) || mpz_cmp (rpub.q, rpriv.q) || mpz_cmp (rpub.g, rpriv.g)) { printf ("%s: the private and public keys are incompatible\n", getprogname ()); printf ("priv:\n%s\n", dcexport_priv (priv)); printf ("pub:\n%s\n", dcexport_pub (pub)); exit (-1); } else { /* step 1a: compute the Diffie-Hellman secret (use mpz_init, mpz_powm, mpz_clear; look at elgamal.c in the libdcrypt source directory for sample usage */ char *Diffie_Hellman_Secret_String = 0; { mpz_t dhSecretInt; mpz_init(dhSecretInt); mpz_powm(dhSecretInt, rpub.y, rpriv.x, rpub.p); reserve = cat_mpz(&Diffie_Hellman_Secret_String, dhSecretInt); /* EC need 0; MALLOC */ mpz_clear(dhSecretInt); if (reserve) { free(Diffie_Hellman_Secret_String); printf("error allocating memory\n"); exit(1); } /* printf("Diffie_Hellman_Secret_String: %s\n",Diffie_Hellman_Secret_String); */ } /* step 1b: order the IDs lexicographically */ char *firstId = NULL, *secondId = NULL; if (strcmp (priv_id, pub_id) < 0) { firstId = priv_id; secondId = pub_id; } else { firstId = pub_id; secondId = priv_id; } /* step 1c: hash DH secret and ordered id pair into a master key */ char key_master[20]; { sha1_ctx shaCipherText; sha1_init(&shaCipherText); sha1_update(&shaCipherText, Diffie_Hellman_Secret_String, strlen(Diffie_Hellman_Secret_String)); char *id12; size_t len1, len2; len1 = strlen(firstId); len2 = strlen(secondId); id12 = (char*)malloc(len1+len2+1); /* +1 for \0 */ strcpy(id12, firstId); strcat(id12, secondId); assert(strlen(id12) == len1+len2); sha1_update(&shaCipherText, id12, len1+len2); free(id12); sha1_final(&shaCipherText, (void*)key_master); /*20 bytes*/ } /* step 2: derive the shared key from the label and the master key */ /*I will work with minimum requirement satisfaction model. Thanks to the open source community for providing me with enough reasoning for that.*/ char sizeofkey[32]; { char sizeofkey_0[20]; size_t len0 = strlen(label)+7; char *label0 = (char*)malloc(len0); strcpy(label0, label); strcat(label0, "AES-CTR"); hmac_sha1(key_master, 20, sizeofkey_0, label0, len0); free(label0); char sizeofkey_1[20]; size_t len1 = strlen(label)+9; char *label1 = (char*)malloc(len1); strcpy(label1, label); strcat(label1, "CBC-MAC"); hmac_sha1(key_master, 20, sizeofkey_1, label1, len1); free(label1); strncpy(sizeofkey, sizeofkey_0, 16); strncpy(sizeofkey+16, sizeofkey_1, 16); } /* step 3: armor the shared key and write it to file. Filename should be of the form <label>-<priv_id>.b64 size_t fn_len = strlen(label)+1+strlen(priv_id)+1+strlen(pub_id)+4+1; */ char *fn = (char *) malloc(32); fn = armor64(sizeofkey, 32); *(fn + 32) = '\0'; int fdsk; fdsk = open (label, O_WRONLY|O_TRUNC|O_CREAT, 0600); int status; status = write (fdsk, fn, strlen (fn)); printf("value of status: %d\n", status); status = write (fdsk, "\n", 1); printf("value of status: %d\n", status); free (fn); close (fdsk); } }
/* this function signs the session id (known as H) as a string then the content of sigbuf */ STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf, PRIVATE_KEY *privatekey){ SHACTX ctx; STRING *session_str=string_new(SHA_DIGEST_LEN); unsigned char hash[SHA_DIGEST_LEN+1]; #ifdef HAVE_LIBGCRYPT gcry_sexp_t gcryhash; #endif SIGNATURE *sign; STRING *signature; CRYPTO *crypto=session->current_crypto?session->current_crypto:session->next_crypto; string_fill(session_str,crypto->session_id,SHA_DIGEST_LEN); ctx=sha1_init(); sha1_update(ctx,session_str,string_len(session_str)+4); sha1_update(ctx,buffer_get(sigbuf),buffer_get_len(sigbuf)); sha1_final(hash+1,ctx); hash[0]=0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN); #endif free(session_str); sign=malloc(sizeof(SIGNATURE)); switch(privatekey->type){ case TYPE_DSS: #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&gcryhash,NULL,"%b",SHA_DIGEST_LEN+1,hash); gcry_pk_sign(&sign->dsa_sign,gcryhash,privatekey->dsa_priv); #elif defined HAVE_LIBCRYPTO sign->dsa_sign=DSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->dsa_priv); #ifdef DEBUG_CRYPTO ssh_print_bignum("r",sign->dsa_sign->r); ssh_print_bignum("s",sign->dsa_sign->s); #endif #endif sign->rsa_sign=NULL; break; case TYPE_RSA: #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&gcryhash,NULL,"(data(flags pkcs1)(hash sha1 %b))",SHA_DIGEST_LEN,hash+1); gcry_pk_sign(&sign->rsa_sign,gcryhash,privatekey->rsa_priv); #elif defined HAVE_LIBCRYPTO sign->rsa_sign=RSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->rsa_priv); #endif sign->dsa_sign=NULL; break; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(gcryhash); #endif sign->type=privatekey->type; if(!sign->dsa_sign && !sign->rsa_sign){ #ifdef HAVE_LIBGCRYPT ssh_set_error(session,SSH_FATAL,"Signing : libcrypt error"); #elif HAVE_LIBCRYPTO ssh_set_error(session,SSH_FATAL,"Signing : openssl error"); #endif signature_free(sign); return NULL; } signature=signature_to_string(sign); signature_free(sign); return signature; }
INT64_T cfs_basic_hash(const char *path, const char *algorithm, unsigned char digest[CHIRP_DIGEST_MAX]) { int fd; INT64_T result; struct chirp_stat info; union { md5_context_t md5; sha1_context_t sha1; } context; enum { MD5, SHA1 } type; if(strcmp(algorithm, "md5") == 0) { type = MD5; md5_init(&context.md5); } else if(strcmp(algorithm, "sha1") == 0) { type = SHA1; sha1_init(&context.sha1); } else { return (errno = EINVAL, -1); } result = cfs->stat(path, &info); if(result < 0) return result; if(S_ISDIR(info.cst_mode)) { errno = EISDIR; return -1; } fd = cfs->open(path, O_RDONLY, 0); if(fd >= 0) { INT64_T total = 0; INT64_T length = info.cst_size; while(length > 0) { char buffer[65536]; INT64_T chunk = MIN((int) sizeof(buffer), length); INT64_T ractual = cfs->pread(fd, buffer, chunk, total); if(ractual <= 0) break; if(type == MD5) md5_update(&context.md5, buffer, ractual); else if(type == SHA1) sha1_update(&context.sha1, buffer, ractual); length -= ractual; total += ractual; } cfs->close(fd); if(type == MD5) { md5_final(digest, &context.md5); return MD5_DIGEST_LENGTH; } else if(type == SHA1) { sha1_final(digest, &context.sha1); return SHA1_DIGEST_LENGTH; } else assert(0); } return -1; }
/* this function signs the session id */ ssh_string ssh_sign_session_id(ssh_session session, ssh_private_key privatekey) { struct ssh_crypto_struct *crypto=session->current_crypto ? session->current_crypto : session->next_crypto; unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; ssh_string signature = NULL; SIGNATURE *sign = NULL; SHACTX ctx = NULL; #ifdef HAVE_LIBGCRYPT gcry_sexp_t data_sexp; #endif ctx = sha1_init(); if (ctx == NULL) { return NULL; } sha1_update(ctx,crypto->session_id,SHA_DIGEST_LEN); sha1_final(hash + 1,ctx); hash[0] = 0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN); #endif sign = malloc(sizeof(SIGNATURE)); if (sign == NULL) { return NULL; } ZERO_STRUCTP(sign); switch(privatekey->type) { case SSH_KEYTYPE_DSS: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&data_sexp, NULL, "%b", SHA_DIGEST_LEN + 1, hash) || gcry_pk_sign(&sign->dsa_sign, data_sexp, privatekey->dsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error"); gcry_sexp_release(data_sexp); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->dsa_priv); if (sign->dsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #ifdef DEBUG_CRYPTO ssh_print_bignum("r",sign->dsa_sign->r); ssh_print_bignum("s",sign->dsa_sign->s); #endif #endif /* HAVE_LIBCRYPTO */ sign->rsa_sign = NULL; break; case SSH_KEYTYPE_RSA: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(hash sha1 %b))", SHA_DIGEST_LEN, hash + 1) || gcry_pk_sign(&sign->rsa_sign, data_sexp, privatekey->rsa_priv)) { ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error"); gcry_sexp_release(data_sexp); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->rsa_priv); if (sign->rsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #endif sign->dsa_sign = NULL; break; default: signature_free(sign); return NULL; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(data_sexp); #endif sign->type = privatekey->type; signature = signature_to_string(sign); signature_free(sign); return signature; }
/* * This function signs the session id (known as H) as a string then * the content of sigbuf */ ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf, ssh_key privatekey) { struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; ssh_string session_str = NULL; ssh_string signature = NULL; SIGNATURE *sign = NULL; SHACTX ctx = NULL; #ifdef HAVE_LIBGCRYPT gcry_sexp_t gcryhash; #endif if(privatekey == NULL || !ssh_key_is_private(privatekey)) { return NULL; } session_str = ssh_string_new(SHA_DIGEST_LEN); if (session_str == NULL) { return NULL; } ssh_string_fill(session_str, crypto->session_id, SHA_DIGEST_LEN); ctx = sha1_init(); if (ctx == NULL) { ssh_string_free(session_str); return NULL; } sha1_update(ctx, session_str, ssh_string_len(session_str) + 4); ssh_string_free(session_str); sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); sha1_final(hash + 1,ctx); hash[0] = 0; #ifdef DEBUG_CRYPTO ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN); #endif sign = malloc(sizeof(SIGNATURE)); if (sign == NULL) { return NULL; } switch(privatekey->type) { case SSH_KEYTYPE_DSS: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&gcryhash, NULL, "%b", SHA_DIGEST_LEN + 1, hash) || gcry_pk_sign(&sign->dsa_sign, gcryhash, privatekey->dsa)) { ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error"); gcry_sexp_release(gcryhash); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->dsa); if (sign->dsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #ifdef DEBUG_CRYPTO ssh_print_bignum("r", sign->dsa_sign->r); ssh_print_bignum("s", sign->dsa_sign->s); #endif #endif /* HAVE_LIBCRYPTO */ sign->rsa_sign = NULL; break; case SSH_KEYTYPE_RSA: #ifdef HAVE_LIBGCRYPT if (gcry_sexp_build(&gcryhash, NULL, "(data(flags pkcs1)(hash sha1 %b))", SHA_DIGEST_LEN, hash + 1) || gcry_pk_sign(&sign->rsa_sign, gcryhash, privatekey->rsa)) { ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error"); gcry_sexp_release(gcryhash); signature_free(sign); return NULL; } #elif defined HAVE_LIBCRYPTO sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN, privatekey->rsa); if (sign->rsa_sign == NULL) { ssh_set_error(session, SSH_FATAL, "Signing: openssl error"); signature_free(sign); return NULL; } #endif sign->dsa_sign = NULL; break; default: signature_free(sign); return NULL; } #ifdef HAVE_LIBGCRYPT gcry_sexp_release(gcryhash); #endif sign->type = privatekey->type; signature = signature_to_string(sign); signature_free(sign); return signature; }