Blame src/dh.c

Packit 6c0a39
/*
Packit 6c0a39
 * dh.c - Diffie-Helman algorithm code against SSH 2
Packit 6c0a39
 *
Packit 6c0a39
 * This file is part of the SSH Library
Packit 6c0a39
 *
Packit 6c0a39
 * Copyright (c) 2003-2018 by Aris Adamantiadis
Packit 6c0a39
 * Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
Packit 6c0a39
 * Copyright (c) 2012      by Dmitriy Kuznetsov <dk@yandex.ru>
Packit 6c0a39
 *
Packit 6c0a39
 * The SSH Library is free software; you can redistribute it and/or modify
Packit 6c0a39
 * it under the terms of the GNU Lesser General Public License as published by
Packit 6c0a39
 * the Free Software Foundation; either version 2.1 of the License, or (at your
Packit 6c0a39
 * option) any later version.
Packit 6c0a39
 *
Packit 6c0a39
 * The SSH Library is distributed in the hope that it will be useful, but
Packit 6c0a39
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit 6c0a39
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
Packit 6c0a39
 * License for more details.
Packit 6c0a39
 *
Packit 6c0a39
 * You should have received a copy of the GNU Lesser General Public License
Packit 6c0a39
 * along with the SSH Library; see the file COPYING.  If not, write to
Packit 6c0a39
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
Packit 6c0a39
 * MA 02111-1307, USA.
Packit 6c0a39
 */
Packit 6c0a39
Packit 6c0a39
#include "config.h"
Packit 6c0a39
Packit 6c0a39
#include "libssh/priv.h"
Packit 6c0a39
#include "libssh/crypto.h"
Packit 6c0a39
#include "libssh/buffer.h"
Packit 6c0a39
#include "libssh/session.h"
Packit 6c0a39
#include "libssh/misc.h"
Packit 6c0a39
#include "libssh/dh.h"
Packit 6c0a39
#include "libssh/ssh2.h"
Packit 6c0a39
#include "libssh/pki.h"
Packit 6c0a39
#include "libssh/bignum.h"
Packit 6c0a39
Packit 6c0a39
static unsigned char p_group1_value[] = {
Packit 6c0a39
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit 6c0a39
        0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit 6c0a39
        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit 6c0a39
        0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit 6c0a39
        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit 6c0a39
        0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit 6c0a39
        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit 6c0a39
        0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit 6c0a39
        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit 6c0a39
        0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
Packit 6c0a39
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
Packit 6c0a39
#define P_GROUP1_LEN 128	/* Size in bytes of the p number */
Packit 6c0a39
Packit 6c0a39
static unsigned char p_group14_value[] = {
Packit 6c0a39
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit 6c0a39
        0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit 6c0a39
        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit 6c0a39
        0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit 6c0a39
        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit 6c0a39
        0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit 6c0a39
        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit 6c0a39
        0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit 6c0a39
        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit 6c0a39
        0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
Packit 6c0a39
        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
Packit 6c0a39
        0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
Packit 6c0a39
        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
Packit 6c0a39
        0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
Packit 6c0a39
        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
Packit 6c0a39
        0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
Packit 6c0a39
        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
Packit 6c0a39
        0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
Packit 6c0a39
        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
Packit 6c0a39
        0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
Packit 6c0a39
        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
Packit 6c0a39
        0xFF, 0xFF, 0xFF, 0xFF};
Packit 6c0a39
Packit 6c0a39
#define P_GROUP14_LEN 256 /* Size in bytes of the p number for group 14 */
Packit 6c0a39
Packit 6c0a39
static unsigned char p_group16_value[] = {
Packit 6c0a39
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit 6c0a39
    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit 6c0a39
    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit 6c0a39
    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit 6c0a39
    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit 6c0a39
    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit 6c0a39
    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit 6c0a39
    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit 6c0a39
    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit 6c0a39
    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
Packit 6c0a39
    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
Packit 6c0a39
    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
Packit 6c0a39
    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
Packit 6c0a39
    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
Packit 6c0a39
    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
Packit 6c0a39
    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
Packit 6c0a39
    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
Packit 6c0a39
    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
Packit 6c0a39
    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
Packit 6c0a39
    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
Packit 6c0a39
    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
Packit 6c0a39
    0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
Packit 6c0a39
    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
Packit 6c0a39
    0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
Packit 6c0a39
    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
Packit 6c0a39
    0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
Packit 6c0a39
    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
Packit 6c0a39
    0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
Packit 6c0a39
    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
Packit 6c0a39
    0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
Packit 6c0a39
    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
Packit 6c0a39
    0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
Packit 6c0a39
    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
Packit 6c0a39
    0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
Packit 6c0a39
    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
Packit 6c0a39
    0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
Packit 6c0a39
    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
Packit 6c0a39
    0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
Packit 6c0a39
    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
Packit 6c0a39
    0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
Packit 6c0a39
    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
Packit 6c0a39
    0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
Packit 6c0a39
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
Packit 6c0a39
Packit 6c0a39
#define P_GROUP16_LEN 512 /* Size in bytes of the p number for group 16 */
Packit 6c0a39
Packit 6c0a39
static unsigned char p_group18_value[] = {
Packit 6c0a39
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit 6c0a39
    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit 6c0a39
    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit 6c0a39
    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit 6c0a39
    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit 6c0a39
    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit 6c0a39
    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit 6c0a39
    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit 6c0a39
    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit 6c0a39
    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
Packit 6c0a39
    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
Packit 6c0a39
    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
Packit 6c0a39
    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
Packit 6c0a39
    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
Packit 6c0a39
    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
Packit 6c0a39
    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
Packit 6c0a39
    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
Packit 6c0a39
    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
Packit 6c0a39
    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
Packit 6c0a39
    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
Packit 6c0a39
    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
Packit 6c0a39
    0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
Packit 6c0a39
    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
Packit 6c0a39
    0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
Packit 6c0a39
    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
Packit 6c0a39
    0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
Packit 6c0a39
    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
Packit 6c0a39
    0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
Packit 6c0a39
    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
Packit 6c0a39
    0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
Packit 6c0a39
    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
Packit 6c0a39
    0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
Packit 6c0a39
    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
Packit 6c0a39
    0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
Packit 6c0a39
    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
Packit 6c0a39
    0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
Packit 6c0a39
    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
Packit 6c0a39
    0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
Packit 6c0a39
    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
Packit 6c0a39
    0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
Packit 6c0a39
    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
Packit 6c0a39
    0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
Packit 6c0a39
    0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2,
Packit 6c0a39
    0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
Packit 6c0a39
    0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F,
Packit 6c0a39
    0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
Packit 6c0a39
    0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB,
Packit 6c0a39
    0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
Packit 6c0a39
    0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51,
Packit 6c0a39
    0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
Packit 6c0a39
    0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15,
Packit 6c0a39
    0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
Packit 6c0a39
    0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31,
Packit 6c0a39
    0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
Packit 6c0a39
    0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7,
Packit 6c0a39
    0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
Packit 6c0a39
    0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2,
Packit 6c0a39
    0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
Packit 6c0a39
    0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D,
Packit 6c0a39
    0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
Packit 6c0a39
    0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7,
Packit 6c0a39
    0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
Packit 6c0a39
    0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E,
Packit 6c0a39
    0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
Packit 6c0a39
    0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0,
Packit 6c0a39
    0x73, 0xB9, 0x31, 0xBA, 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
Packit 6c0a39
    0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, 0x25, 0x76, 0xF6, 0x93,
Packit 6c0a39
    0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
Packit 6c0a39
    0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB,
Packit 6c0a39
    0xE3, 0x9D, 0x65, 0x2D, 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
Packit 6c0a39
    0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, 0x13, 0xEB, 0x57, 0xA8,
Packit 6c0a39
    0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
Packit 6c0a39
    0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F,
Packit 6c0a39
    0xA2, 0xC0, 0x87, 0xE8, 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
Packit 6c0a39
    0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, 0x6D, 0x2A, 0x13, 0xF8,
Packit 6c0a39
    0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
Packit 6c0a39
    0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5,
Packit 6c0a39
    0x08, 0x46, 0x85, 0x1D, 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
Packit 6c0a39
    0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, 0xFA, 0xF3, 0x6B, 0xC3,
Packit 6c0a39
    0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
Packit 6c0a39
    0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E,
Packit 6c0a39
    0xD5, 0xEE, 0x38, 0x2B, 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
Packit 6c0a39
    0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, 0x9E, 0x30, 0x50, 0xE2,
Packit 6c0a39
    0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
Packit 6c0a39
    0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
Packit 6c0a39
    0xFF, 0xFF, 0xFF, 0xFF};
Packit 6c0a39
Packit 6c0a39
#define P_GROUP18_LEN 1024 /* Size in bytes of the p number for group 18 */
Packit 6c0a39
Packit 6c0a39
bignum ssh_dh_generator;
Packit 6c0a39
bignum ssh_dh_group1;
Packit 6c0a39
bignum ssh_dh_group14;
Packit 6c0a39
bignum ssh_dh_group16;
Packit 6c0a39
bignum ssh_dh_group18;
Packit 6c0a39
static int dh_crypto_initialized;
Packit 6c0a39
Packit 6c0a39
/**
Packit 6c0a39
 * @internal
Packit 6c0a39
 * @brief Initialize global constants used in DH key agreement
Packit 6c0a39
 * @return SSH_OK on success, SSH_ERROR otherwise.
Packit 6c0a39
 */
Packit 6c0a39
int ssh_dh_init(void)
Packit 6c0a39
{
Packit 6c0a39
    unsigned long g_int = 2 ;	/* G is defined as 2 by the ssh2 standards */
Packit 6c0a39
    int rc;
Packit 6c0a39
    if (dh_crypto_initialized) {
Packit 6c0a39
        return SSH_OK;
Packit 6c0a39
    }
Packit 6c0a39
    dh_crypto_initialized = 1;
Packit 6c0a39
Packit 6c0a39
    ssh_dh_generator = bignum_new();
Packit 6c0a39
    if (ssh_dh_generator == NULL) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    rc = bignum_set_word(ssh_dh_generator, g_int);
Packit 6c0a39
    if (rc != 1) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    bignum_bin2bn(p_group1_value, P_GROUP1_LEN, &ssh_dh_group1);
Packit 6c0a39
    if (ssh_dh_group1 == NULL) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    bignum_bin2bn(p_group14_value, P_GROUP14_LEN, &ssh_dh_group14);
Packit 6c0a39
    if (ssh_dh_group14 == NULL) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    bignum_bin2bn(p_group16_value, P_GROUP16_LEN, &ssh_dh_group16);
Packit 6c0a39
    if (ssh_dh_group16 == NULL) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    bignum_bin2bn(p_group18_value, P_GROUP18_LEN, &ssh_dh_group18);
Packit 6c0a39
    if (ssh_dh_group18 == NULL) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    return 0;
Packit 6c0a39
error:
Packit 6c0a39
    ssh_dh_finalize();
Packit 6c0a39
    return SSH_ERROR;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/**
Packit 6c0a39
 * @internal
Packit 6c0a39
 * @brief Finalize and free global constants used in DH key agreement
Packit 6c0a39
 */
Packit 6c0a39
void ssh_dh_finalize(void)
Packit 6c0a39
{
Packit 6c0a39
    if (!dh_crypto_initialized) {
Packit 6c0a39
        return;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    bignum_safe_free(ssh_dh_generator);
Packit 6c0a39
    bignum_safe_free(ssh_dh_group1);
Packit 6c0a39
    bignum_safe_free(ssh_dh_group14);
Packit 6c0a39
    bignum_safe_free(ssh_dh_group16);
Packit 6c0a39
    bignum_safe_free(ssh_dh_group18);
Packit 6c0a39
Packit 6c0a39
    dh_crypto_initialized = 0;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
int ssh_dh_import_next_pubkey_blob(ssh_session session, ssh_string pubkey_blob)
Packit 6c0a39
{
Packit 6c0a39
    return ssh_pki_import_pubkey_blob(pubkey_blob,
Packit 6c0a39
                                      &session->next_crypto->server_pubkey);
Packit 6c0a39
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
static SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply);
Packit 6c0a39
Packit 6c0a39
static ssh_packet_callback dh_client_callbacks[]= {
Packit 6c0a39
    ssh_packet_client_dh_reply
Packit 6c0a39
};
Packit 6c0a39
Packit 6c0a39
static struct ssh_packet_callbacks_struct ssh_dh_client_callbacks = {
Packit 6c0a39
    .start = SSH2_MSG_KEXDH_REPLY,
Packit 6c0a39
    .n_callbacks = 1,
Packit 6c0a39
    .callbacks = dh_client_callbacks,
Packit 6c0a39
    .user = NULL
Packit 6c0a39
};
Packit 6c0a39
Packit 6c0a39
/** @internal
Packit 6c0a39
 * @brief Starts diffie-hellman-group1 key exchange
Packit 6c0a39
 */
Packit 6c0a39
int ssh_client_dh_init(ssh_session session){
Packit 6c0a39
  struct ssh_crypto_struct *crypto = session->next_crypto;
Packit 6c0a39
  const_bignum pubkey;
Packit 6c0a39
  int rc;
Packit 6c0a39
Packit 6c0a39
  rc = ssh_dh_init_common(crypto);
Packit 6c0a39
  if (rc == SSH_ERROR) {
Packit 6c0a39
    goto error;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  rc = ssh_dh_keypair_gen_keys(crypto->dh_ctx, DH_CLIENT_KEYPAIR);
Packit 6c0a39
  if (rc == SSH_ERROR){
Packit 6c0a39
      goto error;
Packit 6c0a39
  }
Packit 6c0a39
  rc = ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_CLIENT_KEYPAIR,
Packit 6c0a39
                               NULL, &pubkey);
Packit 6c0a39
  if (rc != SSH_OK) {
Packit 6c0a39
    goto error;
Packit 6c0a39
  }
Packit 6c0a39
  rc = ssh_buffer_pack(session->out_buffer, "bB", SSH2_MSG_KEXDH_INIT, pubkey);
Packit 6c0a39
  if (rc != SSH_OK) {
Packit 6c0a39
    goto error;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  /* register the packet callbacks */
Packit 6c0a39
  ssh_packet_set_callbacks(session, &ssh_dh_client_callbacks);
Packit 6c0a39
  session->dh_handshake_state = DH_STATE_INIT_SENT;
Packit 6c0a39
Packit 6c0a39
  rc = ssh_packet_send(session);
Packit 6c0a39
  return rc;
Packit 6c0a39
error:
Packit 6c0a39
  ssh_dh_cleanup(crypto);
Packit 6c0a39
  return SSH_ERROR;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){
Packit 6c0a39
  struct ssh_crypto_struct *crypto=session->next_crypto;
Packit 6c0a39
  ssh_string pubkey_blob = NULL;
Packit 6c0a39
  bignum server_pubkey;
Packit 6c0a39
  int rc;
Packit 6c0a39
Packit 6c0a39
  (void)type;
Packit 6c0a39
  (void)user;
Packit 6c0a39
Packit 6c0a39
  ssh_packet_remove_callbacks(session, &ssh_dh_client_callbacks);
Packit 6c0a39
Packit 6c0a39
  rc = ssh_buffer_unpack(packet, "SBS", &pubkey_blob, &server_pubkey,
Packit 6c0a39
          &crypto->dh_server_signature);
Packit 6c0a39
  if (rc == SSH_ERROR) {
Packit 6c0a39
      goto error;
Packit 6c0a39
  }
Packit 6c0a39
  rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
Packit 6c0a39
                               NULL, server_pubkey);
Packit 6c0a39
  if (rc != SSH_OK) {
Packit 6c0a39
      bignum_safe_free(server_pubkey);
Packit 6c0a39
      goto error;
Packit 6c0a39
  }
Packit 6c0a39
  rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
Packit Service fcc0d2
  SSH_STRING_FREE(pubkey_blob);
Packit 6c0a39
  if (rc != 0) {
Packit 6c0a39
      goto error;
Packit 6c0a39
  }
Packit 6c0a39
  
Packit 6c0a39
  rc = ssh_dh_compute_shared_secret(session->next_crypto->dh_ctx,
Packit 6c0a39
                                    DH_CLIENT_KEYPAIR, DH_SERVER_KEYPAIR,
Packit 6c0a39
                                    &session->next_crypto->shared_secret);
Packit Service fcc0d2
  ssh_dh_debug_crypto(session->next_crypto);
Packit 6c0a39
  if (rc == SSH_ERROR){
Packit 6c0a39
    ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
Packit 6c0a39
    goto error;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  /* Send the MSG_NEWKEYS */
Packit 6c0a39
  if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
Packit 6c0a39
    goto error;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  rc=ssh_packet_send(session);
Packit 6c0a39
  if (rc == SSH_ERROR) {
Packit 6c0a39
    goto error;
Packit 6c0a39
  }
Packit 6c0a39
Packit 6c0a39
  SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
Packit 6c0a39
  session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
Packit 6c0a39
  return SSH_PACKET_USED;
Packit 6c0a39
error:
Packit 6c0a39
  ssh_dh_cleanup(session->next_crypto);
Packit 6c0a39
  session->session_state=SSH_SESSION_STATE_ERROR;
Packit 6c0a39
  return SSH_PACKET_USED;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
#ifdef WITH_SERVER
Packit 6c0a39
Packit 6c0a39
static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init);
Packit 6c0a39
Packit 6c0a39
static ssh_packet_callback dh_server_callbacks[] = {
Packit 6c0a39
    ssh_packet_server_dh_init,
Packit 6c0a39
};
Packit 6c0a39
Packit 6c0a39
static struct ssh_packet_callbacks_struct ssh_dh_server_callbacks = {
Packit 6c0a39
    .start = SSH2_MSG_KEXDH_INIT,
Packit 6c0a39
    .n_callbacks = 1,
Packit 6c0a39
    .callbacks = dh_server_callbacks,
Packit 6c0a39
    .user = NULL
Packit 6c0a39
};
Packit 6c0a39
Packit 6c0a39
/** @internal
Packit 6c0a39
 * @brief sets up the diffie-hellman-groupx kex callbacks
Packit 6c0a39
 */
Packit 6c0a39
void ssh_server_dh_init(ssh_session session){
Packit 6c0a39
    /* register the packet callbacks */
Packit 6c0a39
    ssh_packet_set_callbacks(session, &ssh_dh_server_callbacks);
Packit 6c0a39
Packit 6c0a39
    ssh_dh_init_common(session->next_crypto);
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/** @internal
Packit 6c0a39
 * @brief processes a SSH_MSG_KEXDH_INIT or SSH_MSG_KEX_DH_GEX_INIT packet and sends
Packit 6c0a39
 * the appropriate SSH_MSG_KEXDH_REPLY or SSH_MSG_KEX_DH_GEX_REPLY
Packit 6c0a39
 */
Packit 6c0a39
int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet)
Packit 6c0a39
{
Packit 6c0a39
    struct ssh_crypto_struct *crypto = session->next_crypto;
Packit 6c0a39
    ssh_key privkey = NULL;
Packit Service fcc0d2
    enum ssh_digest_e digest = SSH_DIGEST_AUTO;
Packit 6c0a39
    ssh_string sig_blob = NULL;
Packit 6c0a39
    ssh_string pubkey_blob = NULL;
Packit 6c0a39
    bignum client_pubkey;
Packit 6c0a39
    const_bignum server_pubkey;
Packit 6c0a39
    int packet_type;
Packit 6c0a39
    int rc;
Packit 6c0a39
Packit 6c0a39
    rc = ssh_buffer_unpack(packet, "B", &client_pubkey);
Packit 6c0a39
    if (rc == SSH_ERROR) {
Packit 6c0a39
        ssh_set_error(session, SSH_FATAL, "No e number in client request");
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_CLIENT_KEYPAIR,
Packit 6c0a39
                                 NULL, client_pubkey);
Packit 6c0a39
    if (rc != SSH_OK) {
Packit 6c0a39
        bignum_safe_free(client_pubkey);
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    rc = ssh_dh_keypair_gen_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR);
Packit 6c0a39
    if (rc == SSH_ERROR) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
Packit Service fcc0d2
    rc = ssh_get_key_params(session, &privkey, &digest);
Packit 6c0a39
    if (rc != SSH_OK) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    rc = ssh_dh_compute_shared_secret(crypto->dh_ctx,
Packit 6c0a39
                                      DH_SERVER_KEYPAIR, DH_CLIENT_KEYPAIR,
Packit 6c0a39
                                      &crypto->shared_secret);
Packit Service fcc0d2
    ssh_dh_debug_crypto(crypto);
Packit 6c0a39
    if (rc == SSH_ERROR) {
Packit 6c0a39
        ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    rc = ssh_make_sessionid(session);
Packit 6c0a39
    if (rc != SSH_OK) {
Packit 6c0a39
        ssh_set_error(session, SSH_FATAL, "Could not create a session id");
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit Service fcc0d2
    sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
Packit 6c0a39
    if (sig_blob == NULL) {
Packit 6c0a39
        ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    switch (crypto->kex_type){
Packit 6c0a39
    case SSH_KEX_DH_GROUP1_SHA1:
Packit 6c0a39
    case SSH_KEX_DH_GROUP14_SHA1:
Packit Service fcc0d2
    case SSH_KEX_DH_GROUP14_SHA256:
Packit 6c0a39
    case SSH_KEX_DH_GROUP16_SHA512:
Packit 6c0a39
    case SSH_KEX_DH_GROUP18_SHA512:
Packit 6c0a39
        packet_type = SSH2_MSG_KEXDH_REPLY;
Packit 6c0a39
        break;
Packit 6c0a39
#ifdef WITH_GEX
Packit 6c0a39
    case SSH_KEX_DH_GEX_SHA1:
Packit 6c0a39
    case SSH_KEX_DH_GEX_SHA256:
Packit 6c0a39
        packet_type = SSH2_MSG_KEX_DH_GEX_REPLY;
Packit 6c0a39
        break;
Packit 6c0a39
#endif /* WITH_GEX */
Packit 6c0a39
    default:
Packit 6c0a39
        ssh_set_error(session, SSH_FATAL, "Invalid kex type");
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    rc = ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
Packit 6c0a39
                                 NULL, &server_pubkey);
Packit 6c0a39
    if (rc != SSH_OK){
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
Packit 6c0a39
    if (rc != SSH_OK){
Packit 6c0a39
        ssh_set_error_oom(session);
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    rc = ssh_buffer_pack(session->out_buffer,
Packit 6c0a39
                         "bSBS",
Packit 6c0a39
                         packet_type,
Packit 6c0a39
                         pubkey_blob,
Packit 6c0a39
                         server_pubkey,
Packit 6c0a39
                         sig_blob);
Packit 6c0a39
    SSH_STRING_FREE(sig_blob);
Packit 6c0a39
    SSH_STRING_FREE(pubkey_blob);
Packit 6c0a39
    if(rc != SSH_OK) {
Packit 6c0a39
        ssh_set_error_oom(session);
Packit 6c0a39
        ssh_buffer_reinit(session->out_buffer);
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    rc = ssh_packet_send(session);
Packit 6c0a39
    if (rc == SSH_ERROR) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    SSH_LOG(SSH_LOG_DEBUG, "Sent KEX_DH_[GEX]_REPLY");
Packit 6c0a39
Packit 6c0a39
    if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
Packit 6c0a39
        ssh_buffer_reinit(session->out_buffer);
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
Packit 6c0a39
    if (ssh_packet_send(session) == SSH_ERROR) {
Packit 6c0a39
        goto error;
Packit 6c0a39
    }
Packit 6c0a39
    SSH_LOG(SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent");
Packit 6c0a39
Packit 6c0a39
    return SSH_OK;
Packit 6c0a39
error:
Packit 6c0a39
    SSH_STRING_FREE(sig_blob);
Packit 6c0a39
    SSH_STRING_FREE(pubkey_blob);
Packit 6c0a39
Packit 6c0a39
    session->session_state = SSH_SESSION_STATE_ERROR;
Packit 6c0a39
    ssh_dh_cleanup(session->next_crypto);
Packit 6c0a39
    return SSH_ERROR;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/** @internal
Packit 6c0a39
 * @brief parse an incoming SSH_MSG_KEXDH_INIT packet and complete
Packit 6c0a39
 *        Diffie-Hellman key exchange
Packit 6c0a39
 **/
Packit 6c0a39
static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init){
Packit 6c0a39
    (void)type;
Packit 6c0a39
    (void)user;
Packit 6c0a39
    SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_KEXDH_INIT");
Packit 6c0a39
    ssh_packet_remove_callbacks(session, &ssh_dh_server_callbacks);
Packit 6c0a39
    ssh_server_dh_process_init(session, packet);
Packit 6c0a39
    return SSH_PACKET_USED;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/** @internal
Packit 6c0a39
 * @brief Choose a fallback group for the DH Group exchange if the
Packit 6c0a39
 * moduli file is not readable
Packit 6c0a39
 * @param[in] pmax maximum requestsd group size
Packit 6c0a39
 * @param[out] modulus
Packit 6c0a39
 * @param[out] generator
Packit 6c0a39
 * @returns SSH_OK on success, SSH_ERROR otherwise
Packit 6c0a39
 */
Packit 6c0a39
int ssh_fallback_group(uint32_t pmax,
Packit 6c0a39
                       bignum *modulus,
Packit 6c0a39
                       bignum *generator)
Packit 6c0a39
{
Packit 6c0a39
    *modulus = NULL;
Packit 6c0a39
    *generator = NULL;
Packit 6c0a39
Packit 6c0a39
    if (pmax < 3072) {
Packit 6c0a39
        bignum_dup(ssh_dh_group14, modulus);
Packit 6c0a39
    } else if (pmax < 6144) {
Packit 6c0a39
        bignum_dup(ssh_dh_group16, modulus);
Packit 6c0a39
    } else {
Packit 6c0a39
        bignum_dup(ssh_dh_group18, modulus);
Packit 6c0a39
    }
Packit 6c0a39
    if (*modulus == NULL) {
Packit 6c0a39
        return SSH_ERROR;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    bignum_dup(ssh_dh_generator, generator);
Packit 6c0a39
    if (*generator == NULL) {
Packit 6c0a39
        bignum_safe_free((*modulus));
Packit 6c0a39
        return SSH_ERROR;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    return SSH_OK;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
#endif /* WITH_SERVER */
Packit 6c0a39
Packit 6c0a39
/**
Packit 6c0a39
 * @addtogroup libssh_session
Packit 6c0a39
 *
Packit 6c0a39
 * @{
Packit 6c0a39
 */
Packit 6c0a39
Packit 6c0a39
bool ssh_dh_is_known_group(bignum modulus, bignum generator)
Packit 6c0a39
{
Packit 6c0a39
    int cmp, bits;
Packit 6c0a39
    bignum m = NULL;
Packit 6c0a39
Packit 6c0a39
    bits = bignum_num_bits(modulus);
Packit 6c0a39
    if (bits < 3072) {
Packit 6c0a39
        m = ssh_dh_group14;
Packit 6c0a39
    } else if (bits < 6144) {
Packit 6c0a39
        m = ssh_dh_group16;
Packit 6c0a39
    } else {
Packit 6c0a39
        m = ssh_dh_group18;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    cmp = bignum_cmp(m, modulus);
Packit 6c0a39
    if (cmp != 0) {
Packit 6c0a39
        return false;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    cmp = bignum_cmp(ssh_dh_generator, generator);
Packit 6c0a39
    if (cmp != 0) {
Packit 6c0a39
        return false;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    SSH_LOG(SSH_LOG_TRACE, "The received primes in FIPS are known");
Packit 6c0a39
    return true;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
ssh_key ssh_dh_get_current_server_publickey(ssh_session session)
Packit 6c0a39
{
Packit 6c0a39
    if (session->current_crypto == NULL) {
Packit 6c0a39
        return NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    return session->current_crypto->server_pubkey;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/* Caller need to free the blob */
Packit 6c0a39
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
Packit 6c0a39
                                     ssh_string *pubkey_blob)
Packit 6c0a39
{
Packit 6c0a39
    const ssh_key pubkey = ssh_dh_get_current_server_publickey(session);
Packit 6c0a39
Packit 6c0a39
    return ssh_pki_export_pubkey_blob(pubkey, pubkey_blob);
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
ssh_key ssh_dh_get_next_server_publickey(ssh_session session)
Packit 6c0a39
{
Packit 6c0a39
    return session->next_crypto->server_pubkey;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/* Caller need to free the blob */
Packit 6c0a39
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
Packit 6c0a39
                                          ssh_string *pubkey_blob)
Packit 6c0a39
{
Packit 6c0a39
    const ssh_key pubkey = ssh_dh_get_next_server_publickey(session);
Packit 6c0a39
Packit 6c0a39
    return ssh_pki_export_pubkey_blob(pubkey, pubkey_blob);
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/**
Packit 6c0a39
 * @internal
Packit 6c0a39
 *
Packit 6c0a39
 * @brief Convert a buffer into an unpadded base64 string.
Packit 6c0a39
 * The caller has to free the memory.
Packit 6c0a39
 *
Packit 6c0a39
 * @param  hash         What should be converted to a base64 string.
Packit 6c0a39
 *
Packit 6c0a39
 * @param  len          Length of the buffer to convert.
Packit 6c0a39
 *
Packit 6c0a39
 * @return              The base64 string or NULL on error.
Packit 6c0a39
 *
Packit 6c0a39
 * @see ssh_string_free_char()
Packit 6c0a39
 */
Packit 6c0a39
static char *ssh_get_b64_unpadded(const unsigned char *hash, size_t len)
Packit 6c0a39
{
Packit 6c0a39
    char *b64_padded = NULL;
Packit 6c0a39
    char *b64_unpadded = NULL;
Packit 6c0a39
    size_t k;
Packit 6c0a39
Packit 6c0a39
    b64_padded = (char *)bin_to_base64(hash, (int)len);
Packit 6c0a39
    if (b64_padded == NULL) {
Packit 6c0a39
        return NULL;
Packit 6c0a39
    }
Packit 6c0a39
    for (k = strlen(b64_padded); k != 0 && b64_padded[k-1] == '='; k--);
Packit 6c0a39
Packit 6c0a39
    b64_unpadded = strndup(b64_padded, k);
Packit 6c0a39
    SAFE_FREE(b64_padded);
Packit 6c0a39
Packit 6c0a39
    return b64_unpadded;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/**
Packit 6c0a39
 * @brief Get a hash as a human-readable hex- or base64-string.
Packit 6c0a39
 *
Packit Service fcc0d2
 * This gets an allocated fingerprint hash.  If it is a SHA sum, it will
Packit Service fcc0d2
 * return an unpadded base64 strings.  If it is a MD5 sum, it will return hex
Packit Service fcc0d2
 * string. Either way, the output is prepended by the hash-type.
Packit 6c0a39
 *
Packit Service fcc0d2
 * @warning Do NOT use MD5 or SHA1! Those hash functions are being deprecated.
Packit 6c0a39
 *
Packit Service fcc0d2
 * @param  type         Which sort of hash is given, use
Packit Service fcc0d2
 *                      SSH_PUBLICKEY_HASH_SHA256 or better.
Packit Service fcc0d2
 *
Packit Service fcc0d2
 * @param  hash         The hash to be converted to fingerprint.
Packit 6c0a39
 *
Packit 6c0a39
 * @param  len          Length of the buffer to convert.
Packit 6c0a39
 *
Packit 6c0a39
 * @return Returns the allocated fingerprint hash or NULL on error.
Packit 6c0a39
 *
Packit 6c0a39
 * @see ssh_string_free_char()
Packit 6c0a39
 */
Packit 6c0a39
char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
Packit 6c0a39
                               unsigned char *hash,
Packit 6c0a39
                               size_t len)
Packit 6c0a39
{
Packit 6c0a39
    const char *prefix = "UNKNOWN";
Packit 6c0a39
    char *fingerprint = NULL;
Packit 6c0a39
    char *str = NULL;
Packit 6c0a39
    size_t str_len;
Packit 6c0a39
    int rc;
Packit 6c0a39
Packit 6c0a39
    switch (type) {
Packit 6c0a39
    case SSH_PUBLICKEY_HASH_SHA1:
Packit 6c0a39
    case SSH_PUBLICKEY_HASH_SHA256:
Packit 6c0a39
        fingerprint = ssh_get_b64_unpadded(hash, len);
Packit 6c0a39
        break;
Packit 6c0a39
    case SSH_PUBLICKEY_HASH_MD5:
Packit 6c0a39
        fingerprint = ssh_get_hexa(hash, len);
Packit 6c0a39
        break;
Packit 6c0a39
    }
Packit 6c0a39
    if (fingerprint == NULL) {
Packit 6c0a39
        return NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    switch (type) {
Packit 6c0a39
    case SSH_PUBLICKEY_HASH_MD5:
Packit 6c0a39
        prefix = "MD5";
Packit 6c0a39
        break;
Packit 6c0a39
    case SSH_PUBLICKEY_HASH_SHA1:
Packit 6c0a39
        prefix = "SHA1";
Packit 6c0a39
        break;
Packit 6c0a39
    case SSH_PUBLICKEY_HASH_SHA256:
Packit 6c0a39
        prefix = "SHA256";
Packit 6c0a39
        break;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    str_len = strlen(prefix);
Packit 6c0a39
    if (str_len + 1 + strlen(fingerprint) + 1 < str_len) {
Packit 6c0a39
        SAFE_FREE(fingerprint);
Packit 6c0a39
        return NULL;
Packit 6c0a39
    }
Packit 6c0a39
    str_len += 1 + strlen(fingerprint) + 1;
Packit 6c0a39
Packit 6c0a39
    str = malloc(str_len);
Packit 6c0a39
    if (str == NULL) {
Packit 6c0a39
        SAFE_FREE(fingerprint);
Packit 6c0a39
        return NULL;
Packit 6c0a39
    }
Packit 6c0a39
    rc = snprintf(str, str_len, "%s:%s", prefix, fingerprint);
Packit 6c0a39
    SAFE_FREE(fingerprint);
Packit 6c0a39
    if (rc < 0 || rc < (int)(str_len - 1)) {
Packit 6c0a39
        SAFE_FREE(str);
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    return str;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/**
Packit 6c0a39
 * @brief Print a hash as a human-readable hex- or base64-string.
Packit 6c0a39
 *
Packit Service fcc0d2
 * This prints an unpadded base64 strings for SHA sums and hex strings for MD5
Packit Service fcc0d2
 * sum.  Either way, the output is prepended by the hash-type.
Packit 6c0a39
 *
Packit Service fcc0d2
 * @param  type         Which sort of hash is given. Use
Packit Service fcc0d2
 *                      SSH_PUBLICKEY_HASH_SHA256 or better.
Packit 6c0a39
 *
Packit Service fcc0d2
 * @param  hash         The hash to be converted to fingerprint.
Packit 6c0a39
 *
Packit 6c0a39
 * @param  len          Length of the buffer to convert.
Packit 6c0a39
 *
Packit 6c0a39
 * @see ssh_get_publickey_hash()
Packit 6c0a39
 * @see ssh_get_fingerprint_hash()
Packit 6c0a39
 */
Packit 6c0a39
void ssh_print_hash(enum ssh_publickey_hash_type type,
Packit 6c0a39
                    unsigned char *hash,
Packit 6c0a39
                    size_t len)
Packit 6c0a39
{
Packit 6c0a39
    char *fingerprint = NULL;
Packit 6c0a39
Packit 6c0a39
    fingerprint = ssh_get_fingerprint_hash(type,
Packit 6c0a39
                                           hash,
Packit 6c0a39
                                           len);
Packit 6c0a39
    if (fingerprint == NULL) {
Packit 6c0a39
        return;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    fprintf(stderr, "%s\n", fingerprint);
Packit 6c0a39
Packit 6c0a39
    SAFE_FREE(fingerprint);
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/** @} */