Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * This file is part of the SSH Library |
3 | | * |
4 | | * Copyright (c) 2014 by Aris Adamantiadis <aris@badcode.be> |
5 | | * |
6 | | * The SSH Library is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or (at your |
9 | | * option) any later version. |
10 | | * |
11 | | * The SSH Library is distributed in the hope that it will be useful, but |
12 | | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
13 | | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
14 | | * License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with the SSH Library; see the file COPYING. If not, write to |
18 | | * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
19 | | * MA 02111-1307, USA. |
20 | | */ |
21 | | |
22 | | #include "config.h" |
23 | | |
24 | | #include <stdio.h> |
25 | | |
26 | | #include "libssh/priv.h" |
27 | | #include "libssh/bignum.h" |
28 | | #include "libssh/string.h" |
29 | | |
30 | | static ssh_string make_bignum_string(bignum num, size_t pad_to_len) |
31 | 56.8k | { |
32 | 56.8k | ssh_string ptr = NULL; |
33 | 56.8k | size_t pad = 0; |
34 | 56.8k | size_t len = bignum_num_bytes(num); |
35 | 56.8k | size_t bits = bignum_num_bits(num); |
36 | | |
37 | 56.8k | if (pad_to_len == 0) { |
38 | | /* If the first bit is set we have a negative number */ |
39 | 56.8k | if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) { |
40 | 34.4k | pad++; |
41 | 34.4k | } |
42 | 56.8k | } else { |
43 | 0 | if (len > pad_to_len) { |
44 | 0 | return NULL; |
45 | 0 | } |
46 | 0 | pad = pad_to_len - len; |
47 | 0 | } |
48 | | |
49 | | #ifdef DEBUG_CRYPTO |
50 | | SSH_LOG(SSH_LOG_TRACE, "%zu bits, %zu bytes, %zu padding", bits, len, pad); |
51 | | #endif /* DEBUG_CRYPTO */ |
52 | | |
53 | 56.8k | ptr = ssh_string_new(len + pad); |
54 | 56.8k | if (ptr == NULL) { |
55 | 0 | return NULL; |
56 | 0 | } |
57 | | |
58 | | /* We have a negative number so we need a leading zero */ |
59 | 56.8k | if (pad) { |
60 | 34.4k | memset(ptr->data, 0, pad); |
61 | 34.4k | } |
62 | | |
63 | 56.8k | bignum_bn2bin(num, len, ptr->data + pad); |
64 | | |
65 | 56.8k | return ptr; |
66 | 56.8k | } |
67 | | |
68 | | ssh_string ssh_make_bignum_string(bignum num) |
69 | 56.8k | { |
70 | 56.8k | return make_bignum_string(num, 0); |
71 | 56.8k | } |
72 | | |
73 | | ssh_string ssh_make_padded_bignum_string(bignum num, size_t pad_len) |
74 | 0 | { |
75 | 0 | return make_bignum_string(num, pad_len); |
76 | 0 | } |
77 | | |
78 | | bignum ssh_make_string_bn(ssh_string string) |
79 | 33.8k | { |
80 | 33.8k | bignum bn = NULL; |
81 | 33.8k | size_t len = ssh_string_len(string); |
82 | | |
83 | | #ifdef DEBUG_CRYPTO |
84 | | SSH_LOG(SSH_LOG_TRACE, |
85 | | "Importing a %zu bits, %zu bytes object ...", |
86 | | len * 8, |
87 | | len); |
88 | | #endif /* DEBUG_CRYPTO */ |
89 | | |
90 | 33.8k | bignum_bin2bn(string->data, (int)len, &bn); |
91 | | |
92 | 33.8k | return bn; |
93 | 33.8k | } |
94 | | |
95 | | /* prints the bignum on stderr */ |
96 | | void ssh_print_bignum(const char *name, const_bignum num) |
97 | 0 | { |
98 | 0 | unsigned char *hex = NULL; |
99 | 0 | if (num != NULL) { |
100 | 0 | bignum_bn2hex(num, &hex); |
101 | 0 | } |
102 | 0 | SSH_LOG(SSH_LOG_DEBUG, |
103 | 0 | "%s value: %s", |
104 | 0 | name, |
105 | 0 | (hex == NULL) ? "(null)" : (char *)hex); |
106 | 0 | ssh_crypto_free(hex); |
107 | 0 | } |