d9e258d5 | /* |
47d40feb | * Copyright (C) 2007-2009 Sourcefire, Inc. |
d9e258d5 | * |
2023340a | * Authors: Tomasz Kojm |
d9e258d5 | * * This program is free software; you can redistribute it and/or modify |
bb34cb31 | * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. |
d9e258d5 | * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software |
48b7b4a7 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. |
d9e258d5 | */ |
6d6e8271 | #if HAVE_CONFIG_H #include "clamav-config.h" #endif |
d9e258d5 | #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include "clamav.h" #include "others.h" |
ba174707 | #include "dsig.h" |
8000d078 | #include "str.h" |
47d40feb | #include "bignum.h" |
d9e258d5 | |
5b68299b | #define CLI_NSTR "118640995551645342603070001658453189751527774412027743746599405743243142607464144767361060640655844749760788890022283424922762488917565551002467771109669598189410434699034532232228621591089508178591428456220796841621637175567590476666928698770143328137383952820383197532047771780196576957695822641224262693037" |
d9e258d5 | |
5b68299b | #define CLI_ESTR "100001027" |
d1c685b8 | static unsigned char cli_ndecode(unsigned char value) |
d9e258d5 | { |
d1c685b8 | unsigned int i; |
d9e258d5 | char ncodec[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; for(i = 0; i < 64; i++) if(ncodec[i] == value) return i; cli_errmsg("cli_ndecode: value out of range\n"); return -1; } |
47d40feb | unsigned char *cli_decodesig(const char *sig, unsigned int plen, mp_int e, mp_int n) |
d9e258d5 | { |
aae7da93 | int i, slen = strlen(sig), dec; |
d1c685b8 | unsigned char *plain; |
47d40feb | mp_int r, p, c; |
d9e258d5 | |
47d40feb | mp_init(&r); mp_init(&c); |
d1c685b8 | for(i = 0; i < slen; i++) { |
e12c29d2 | if((dec = cli_ndecode(sig[i])) < 0) { |
47d40feb | mp_clear(&r); mp_clear(&c); |
d9e258d5 | return NULL; |
e12c29d2 | } |
47d40feb | mp_set_int(&r, dec); mp_mul_2d(&r, 6 * i, &r); mp_add(&r, &c, &c); |
d9e258d5 | } |
d1c685b8 | plain = (unsigned char *) cli_calloc(plen + 1, sizeof(unsigned char)); if(!plain) { cli_errmsg("cli_decodesig: Can't allocate memory for 'plain'\n"); |
47d40feb | mp_clear(&r); mp_clear(&c); |
e12c29d2 | return NULL; } |
47d40feb | mp_init(&p); mp_exptmod(&c, &e, &n, &p); /* plain = cipher^e mod n */ mp_clear(&c); mp_set_int(&c, 256); |
d1c685b8 | for(i = plen - 1; i >= 0; i--) { /* reverse */ |
47d40feb | mp_div(&p, &c, &p, &r); plain[i] = mp_get_int(&r); |
d9e258d5 | } |
47d40feb | mp_clear(&c); mp_clear(&p); mp_clear(&r); |
d9e258d5 | |
d1c685b8 | return plain; |
5b68299b | } |
d9e258d5 | int cli_versig(const char *md5, const char *dsig) { |
47d40feb | mp_int n, e; |
d9e258d5 | char *pt, *pt2; |
5b68299b | |
d9e258d5 | if(strlen(md5) != 32 || !isalnum(md5[0])) { /* someone is trying to fool us with empty/malformed MD5 ? */ cli_errmsg("SECURITY WARNING: MD5 basic test failure.\n"); |
871177cd | return CL_EVERIFY; |
d9e258d5 | } |
47d40feb | mp_init(&n); mp_read_radix(&n, CLI_NSTR, 10); mp_init(&e); mp_read_radix(&e, CLI_ESTR, 10); |
ae307914 | |
5b68299b | if(!(pt = (char *) cli_decodesig(dsig, 16, e, n))) { |
47d40feb | mp_clear(&n); mp_clear(&e); |
871177cd | return CL_EVERIFY; |
9e431a95 | } |
ae307914 | |
8000d078 | pt2 = cli_str2hex(pt, 16); |
d9e258d5 | free(pt); |
5b68299b | cli_dbgmsg("cli_versig: Decoded signature: %s\n", pt2); |
d9e258d5 | if(strncmp(md5, pt2, 32)) { |
5b68299b | cli_dbgmsg("cli_versig: Signature doesn't match.\n"); |
d9e258d5 | free(pt2); |
47d40feb | mp_clear(&n); mp_clear(&e); |
871177cd | return CL_EVERIFY; |
d9e258d5 | } free(pt2); |
47d40feb | mp_clear(&n); mp_clear(&e); |
d9e258d5 | |
5b68299b | cli_dbgmsg("cli_versig: Digital signature is correct.\n"); return CL_SUCCESS; |
d9e258d5 | } |