You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-11-06 16:09:29 +03:00
652 lines
16 KiB
C
652 lines
16 KiB
C
/*
|
|
* keymanagetest.c
|
|
*
|
|
* Expected SUCCESSes: 2 + 2 + 3 for all tests.
|
|
*
|
|
* Returns:
|
|
* Number of FAILUREs.
|
|
*
|
|
*
|
|
* FIX Or how about passing a usmUser name and looking up the entry as
|
|
* a means of getting key material? This means the userList is
|
|
* available from an application...
|
|
*
|
|
* ASSUMES No key management functions return non-zero success codes.
|
|
*
|
|
* Test of generate_Ku(). SUCCESSes: 2
|
|
* Test of generate_kul(). SUCCESSes: 2
|
|
* Test of {encode,decode}_keychange(). SUCCESSes: 3
|
|
*/
|
|
|
|
static char *rcsid = "$Id: keymanagetest.c,v 5.0 2002/04/20 07:30:22 hardaker Exp $"; /* */
|
|
|
|
#include <net-snmp/net-snmp-config.h>
|
|
|
|
#include <stdio.h>
|
|
#ifdef HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif
|
|
|
|
#include "asn1.h"
|
|
#include "snmp_api.h"
|
|
#include "keytools.h"
|
|
#include "tools.h"
|
|
#include "scapi.h"
|
|
#include "transform_oids.h"
|
|
#include "callback.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
extern char *optarg;
|
|
extern int optind, optopt, opterr;
|
|
|
|
|
|
|
|
/*
|
|
* Globals, &c...
|
|
*/
|
|
char *local_progname;
|
|
|
|
#define USAGE "Usage: %s [-h][-aklu][-E <engineID>][-N <newkey>][-O <oldkey>][-P <passphrase>]"
|
|
#define OPTIONLIST "aqE:hklN:O:P:u"
|
|
|
|
int doalltests = 0, dogenKu = 0, dogenkul = 0, dokeychange = 0;
|
|
|
|
#define ALLOPTIONS (doalltests + dogenKu + dogenkul + dokeychange)
|
|
|
|
|
|
#define LOCAL_MAXBUF (1024 * 8)
|
|
#define NL "\n"
|
|
|
|
#define OUTPUTALWAYS(o) fprintf(stdout, "\n\n%s\n\n", o);
|
|
#define OUTPUT(o) if (!bequiet) { OUTPUTALWAYS(o); }
|
|
|
|
#define SUCCESS(s) \
|
|
{ \
|
|
if (!failcount && !bequiet) \
|
|
fprintf(stdout, "\nSUCCESS: %s\n", s); \
|
|
}
|
|
|
|
#define FAILED(e, f) \
|
|
{ \
|
|
if (e != SNMPERR_SUCCESS && !bequiet) { \
|
|
fprintf(stdout, "\nFAILED: %s\n", f); \
|
|
failcount += 1; \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Test specific globals.
|
|
*/
|
|
#define ENGINEID_DEFAULT "1.2.3.4wild"
|
|
#define PASSPHRASE_DEFAULT "Clay's Conclusion: Creativity is great, " \
|
|
"but plagiarism is faster."
|
|
#define OLDKEY_DEFAULT "This is a very old key."
|
|
#define NEWKEY_DEFAULT "This key, on the other hand, is very new."
|
|
|
|
char *engineID = NULL;
|
|
char *passphrase = NULL;
|
|
char *oldkey = NULL;
|
|
char *newkey = NULL;
|
|
int bequiet = 0;
|
|
|
|
|
|
/*
|
|
* Prototypes.
|
|
*/
|
|
void usage(FILE * ofp);
|
|
|
|
int test_genkul(void);
|
|
int test_genKu(void);
|
|
int test_keychange(void);
|
|
|
|
|
|
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int rval = SNMPERR_SUCCESS, failcount = 0;
|
|
char ch;
|
|
|
|
local_progname = argv[0];
|
|
optarg = NULL;
|
|
|
|
/*
|
|
* Parse.
|
|
*/
|
|
while ((ch = getopt(argc, argv, OPTIONLIST)) != EOF) {
|
|
switch (ch) {
|
|
case 'a':
|
|
doalltests = 1;
|
|
break;
|
|
case 'E':
|
|
engineID = optarg;
|
|
break;
|
|
case 'k':
|
|
dokeychange = 1;
|
|
break;
|
|
case 'l':
|
|
dogenkul = 1;
|
|
break;
|
|
case 'N':
|
|
newkey = optarg;
|
|
break;
|
|
case 'O':
|
|
oldkey = optarg;
|
|
break;
|
|
case 'P':
|
|
passphrase = optarg;
|
|
break;
|
|
case 'u':
|
|
dogenKu = 1;
|
|
break;
|
|
case 'q':
|
|
bequiet = 1;
|
|
break;
|
|
case 'h':
|
|
rval = 0;
|
|
default:
|
|
usage(stdout);
|
|
exit(rval);
|
|
}
|
|
|
|
argc -= 1;
|
|
argv += 1;
|
|
if (optarg) {
|
|
argc -= 1;
|
|
argv += 1;
|
|
}
|
|
|
|
optind = 1;
|
|
optarg = NULL;
|
|
} /* endwhile getopt */
|
|
|
|
if ((argc > 1)) {
|
|
usage(stdout);
|
|
exit(1000);
|
|
|
|
} else if (ALLOPTIONS != 1) {
|
|
usage(stdout);
|
|
exit(1000);
|
|
}
|
|
|
|
|
|
/*
|
|
* Test stuff.
|
|
*/
|
|
rval = sc_init();
|
|
FAILED(rval, "sc_init().");
|
|
|
|
if (dogenKu || doalltests) {
|
|
failcount += test_genKu();
|
|
}
|
|
if (dogenkul || doalltests) {
|
|
failcount += test_genkul();
|
|
}
|
|
if (dokeychange || doalltests) {
|
|
failcount += test_keychange();
|
|
}
|
|
|
|
|
|
/*
|
|
* Cleanup.
|
|
*/
|
|
rval = sc_shutdown(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
|
|
NULL, NULL);
|
|
FAILED(rval, "sc_shutdown().");
|
|
|
|
return failcount;
|
|
|
|
} /* end main() */
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
usage(FILE * ofp)
|
|
{
|
|
fprintf(ofp,
|
|
USAGE
|
|
"" NL
|
|
" -a All tests." NL
|
|
" -E [0x]<engineID> snmpEngineID string."
|
|
NL
|
|
" -k Test {encode,decode}_keychange()."
|
|
NL
|
|
" -l generate_kul()."
|
|
NL
|
|
" -h Help."
|
|
NL
|
|
" -N [0x]<newkey> New key (for testing KeyChange TC)."
|
|
NL
|
|
" -O [0x]<oldkey> Old key (for testing KeyChange TC)."
|
|
NL
|
|
" -P <passphrase> Source string for usmUser master key."
|
|
NL
|
|
" -u generate_Ku()."
|
|
NL
|
|
" -q be quiet."
|
|
NL "" NL, local_progname);
|
|
|
|
} /* end usage() */
|
|
|
|
|
|
|
|
|
|
#ifdef EXAMPLE
|
|
/*******************************************************************-o-******
|
|
* test_dosomething
|
|
*
|
|
* Test template.
|
|
*
|
|
* Returns:
|
|
* Number of failures.
|
|
*/
|
|
int
|
|
test_dosomething(void)
|
|
{
|
|
int rval = SNMPERR_SUCCESS, failcount = 0;
|
|
|
|
EM0(1, "UNIMPLEMENTED"); /* EM(1); /* */
|
|
|
|
test_dosomething_quit:
|
|
return failcount;
|
|
|
|
} /* end test_dosomething() */
|
|
#endif /* EXAMPLE */
|
|
|
|
|
|
|
|
/*******************************************************************-o-******
|
|
* test_genKu
|
|
*
|
|
* Returns:
|
|
* Number of failures.
|
|
*
|
|
*
|
|
* Test generation of usmUser master key from a passphrase.
|
|
*
|
|
* ASSUMES Passphrase is made of printable characters!
|
|
*/
|
|
int
|
|
test_genKu(void)
|
|
{
|
|
int rval = SNMPERR_SUCCESS,
|
|
failcount = 0,
|
|
properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5), kulen;
|
|
char *hashname = "usmHMACMD5AuthProtocol.", *s;
|
|
u_char Ku[LOCAL_MAXBUF];
|
|
oid *hashtype = usmHMACMD5AuthProtocol;
|
|
|
|
OUTPUT("Test of generate_Ku --");
|
|
|
|
/*
|
|
* Set passphrase.
|
|
*/
|
|
if (!passphrase) {
|
|
passphrase = PASSPHRASE_DEFAULT;
|
|
}
|
|
if (!bequiet)
|
|
fprintf(stdout, "Passphrase%s:\n\t%s\n\n",
|
|
(passphrase == PASSPHRASE_DEFAULT) ? " (default)" : "",
|
|
passphrase);
|
|
|
|
|
|
test_genKu_again:
|
|
memset(Ku, 0, LOCAL_MAXBUF);
|
|
kulen = LOCAL_MAXBUF;
|
|
|
|
rval = generate_Ku(hashtype, USM_LENGTH_OID_TRANSFORM,
|
|
passphrase, strlen(passphrase), Ku, &kulen);
|
|
FAILED(rval, "generate_Ku().");
|
|
|
|
if (kulen != properlength) {
|
|
FAILED(SNMPERR_GENERR, "Ku length is wrong for this hashtype.");
|
|
}
|
|
|
|
binary_to_hex(Ku, kulen, &s);
|
|
if (!bequiet)
|
|
fprintf(stdout, "Ku (len=%d): %s\n", kulen, s);
|
|
free_zero(s, kulen);
|
|
|
|
SUCCESS(hashname);
|
|
if (!bequiet)
|
|
fprintf(stdout, "\n");
|
|
|
|
if (hashtype == usmHMACMD5AuthProtocol) {
|
|
hashtype = usmHMACSHA1AuthProtocol;
|
|
hashname = "usmHMACSHA1AuthProtocol.";
|
|
properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
|
|
goto test_genKu_again;
|
|
}
|
|
|
|
return failcount;
|
|
|
|
} /* end test_genKu() */
|
|
|
|
|
|
|
|
|
|
/*******************************************************************-o-******
|
|
* test_genkul
|
|
*
|
|
* Returns:
|
|
* Number of failures.
|
|
*
|
|
*
|
|
* Test of generate_kul().
|
|
*
|
|
* A passphrase and engineID are hashed into a master key Ku using
|
|
* both known hash transforms. Localized keys, also using both hash
|
|
* transforms, are generated from each of these master keys.
|
|
*
|
|
* ASSUME generate_Ku is already tested.
|
|
* ASSUME engineID is initially a NULL terminated string.
|
|
*/
|
|
int
|
|
test_genkul(void)
|
|
{
|
|
int rval = SNMPERR_SUCCESS,
|
|
failcount = 0,
|
|
properlength, kulen, kul_len, engineID_len, isdefault = FALSE;
|
|
|
|
char *s = NULL,
|
|
*testname = "Using HMACMD5 to create master key.",
|
|
*hashname_Ku = "usmHMACMD5AuthProtocol", *hashname_kul;
|
|
|
|
u_char Ku[LOCAL_MAXBUF], kul[LOCAL_MAXBUF];
|
|
|
|
oid *hashtype_Ku = usmHMACMD5AuthProtocol, *hashtype_kul;
|
|
|
|
OUTPUT("Test of generate_kul --");
|
|
|
|
|
|
/*
|
|
* Set passphrase and engineID.
|
|
*
|
|
* If engineID begins with 0x, assume it is written in (printable)
|
|
* hex and convert it to binary data.
|
|
*/
|
|
if (!passphrase) {
|
|
passphrase = PASSPHRASE_DEFAULT;
|
|
}
|
|
if (!bequiet)
|
|
fprintf(stdout, "Passphrase%s:\n\t%s\n\n",
|
|
(passphrase == PASSPHRASE_DEFAULT) ? " (default)" : "",
|
|
passphrase);
|
|
|
|
if (!engineID) {
|
|
engineID = ENGINEID_DEFAULT;
|
|
isdefault = TRUE;
|
|
}
|
|
|
|
engineID_len = strlen(engineID);
|
|
|
|
if (tolower(*(engineID + 1)) == 'x') {
|
|
engineID_len = hex_to_binary2(engineID + 2, engineID_len - 2, &s);
|
|
if (engineID_len < 0) {
|
|
FAILED((rval = SNMPERR_GENERR),
|
|
"Could not resolve hex engineID.");
|
|
}
|
|
engineID = s;
|
|
binary_to_hex(engineID, engineID_len, &s);
|
|
}
|
|
|
|
if (!bequiet)
|
|
fprintf(stdout, "engineID%s (len=%d): %s\n\n",
|
|
(isdefault) ? " (default)" : "",
|
|
engineID_len, (s) ? s : engineID);
|
|
if (s) {
|
|
SNMP_FREE(s);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Create a master key using both hash transforms; create localized
|
|
* keys using both hash transforms from each master key.
|
|
*/
|
|
test_genkul_again_master:
|
|
memset(Ku, 0, LOCAL_MAXBUF);
|
|
kulen = LOCAL_MAXBUF;
|
|
hashname_kul = "usmHMACMD5AuthProtocol";
|
|
hashtype_kul = usmHMACMD5AuthProtocol;
|
|
properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
|
|
|
|
|
|
rval = generate_Ku(hashtype_Ku, USM_LENGTH_OID_TRANSFORM,
|
|
passphrase, strlen(passphrase), Ku, &kulen);
|
|
FAILED(rval, "generate_Ku().");
|
|
|
|
binary_to_hex(Ku, kulen, &s);
|
|
if (!bequiet)
|
|
fprintf(stdout,
|
|
"\n\nMaster Ku using \"%s\":\n\t%s\n\n", hashname_Ku, s);
|
|
free_zero(s, kulen);
|
|
|
|
|
|
test_genkul_again_local:
|
|
memset(kul, 0, LOCAL_MAXBUF);
|
|
kul_len = LOCAL_MAXBUF;
|
|
|
|
rval = generate_kul(hashtype_kul, USM_LENGTH_OID_TRANSFORM,
|
|
engineID, engineID_len, Ku, kulen, kul, &kul_len);
|
|
|
|
if ((hashtype_Ku == usmHMACMD5AuthProtocol)
|
|
&& (hashtype_kul == usmHMACSHA1AuthProtocol)) {
|
|
if (rval == SNMPERR_SUCCESS) {
|
|
FAILED(SNMPERR_GENERR,
|
|
"generate_kul SHOULD fail when Ku length is "
|
|
"less than hash transform length.");
|
|
}
|
|
|
|
} else {
|
|
FAILED(rval, "generate_kul().");
|
|
|
|
if (kul_len != properlength) {
|
|
FAILED(SNMPERR_GENERR,
|
|
"kul length is wrong for the given hashtype.");
|
|
}
|
|
|
|
binary_to_hex(kul, kul_len, &s);
|
|
fprintf(stdout, "kul (%s) (len=%d): %s\n",
|
|
((hashtype_Ku == usmHMACMD5AuthProtocol) ? "MD5" : "SHA"),
|
|
kul_len, s);
|
|
free_zero(s, kul_len);
|
|
}
|
|
|
|
|
|
/*
|
|
* Create localized key using the other hash transform, but from
|
|
* * the same master key.
|
|
*/
|
|
if (hashtype_kul == usmHMACMD5AuthProtocol) {
|
|
hashtype_kul = usmHMACSHA1AuthProtocol;
|
|
hashname_kul = "usmHMACSHA1AuthProtocol";
|
|
properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
|
|
goto test_genkul_again_local;
|
|
}
|
|
|
|
SUCCESS(testname);
|
|
|
|
|
|
/*
|
|
* Re-create the master key using the other hash transform.
|
|
*/
|
|
if (hashtype_Ku == usmHMACMD5AuthProtocol) {
|
|
hashtype_Ku = usmHMACSHA1AuthProtocol;
|
|
hashname_Ku = "usmHMACSHA1AuthProtocol";
|
|
testname = "Using HMACSHA1 to create master key.";
|
|
goto test_genkul_again_master;
|
|
}
|
|
|
|
return failcount;
|
|
|
|
} /* end test_genkul() */
|
|
|
|
|
|
|
|
|
|
/*******************************************************************-o-******
|
|
* test_keychange
|
|
*
|
|
* Returns:
|
|
* Number of failures.
|
|
*
|
|
*
|
|
* Test of KeyChange TC implementation.
|
|
*
|
|
* ASSUME newkey and oldkey begin as NULL terminated strings.
|
|
*/
|
|
int
|
|
test_keychange(void)
|
|
{
|
|
int rval = SNMPERR_SUCCESS,
|
|
failcount = 0,
|
|
properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5),
|
|
oldkey_len,
|
|
newkey_len,
|
|
keychange_len,
|
|
temp_len, isdefault_new = FALSE, isdefault_old = FALSE;
|
|
|
|
char *hashname = "usmHMACMD5AuthProtocol.", *s;
|
|
|
|
u_char oldkey_buf[LOCAL_MAXBUF],
|
|
newkey_buf[LOCAL_MAXBUF],
|
|
temp_buf[LOCAL_MAXBUF], keychange_buf[LOCAL_MAXBUF];
|
|
|
|
oid *hashtype = usmHMACMD5AuthProtocol;
|
|
|
|
OUTPUT("Test of KeyChange TC --");
|
|
|
|
|
|
/*
|
|
* Set newkey and oldkey.
|
|
*/
|
|
if (!newkey) { /* newkey */
|
|
newkey = NEWKEY_DEFAULT;
|
|
isdefault_new = TRUE;
|
|
}
|
|
newkey_len = strlen(newkey);
|
|
|
|
if (tolower(*(newkey + 1)) == 'x') {
|
|
newkey_len = hex_to_binary2(newkey + 2, newkey_len - 2, &s);
|
|
if (newkey_len < 0) {
|
|
FAILED((rval = SNMPERR_GENERR),
|
|
"Could not resolve hex newkey.");
|
|
}
|
|
newkey = s;
|
|
binary_to_hex(newkey, newkey_len, &s);
|
|
}
|
|
|
|
if (!oldkey) { /* oldkey */
|
|
oldkey = OLDKEY_DEFAULT;
|
|
isdefault_old = TRUE;
|
|
}
|
|
oldkey_len = strlen(oldkey);
|
|
|
|
if (tolower(*(oldkey + 1)) == 'x') {
|
|
oldkey_len = hex_to_binary2(oldkey + 2, oldkey_len - 2, &s);
|
|
if (oldkey_len < 0) {
|
|
FAILED((rval = SNMPERR_GENERR),
|
|
"Could not resolve hex oldkey.");
|
|
}
|
|
oldkey = s;
|
|
binary_to_hex(oldkey, oldkey_len, &s);
|
|
}
|
|
|
|
|
|
|
|
test_keychange_again:
|
|
memset(oldkey_buf, 0, LOCAL_MAXBUF);
|
|
memset(newkey_buf, 0, LOCAL_MAXBUF);
|
|
memset(keychange_buf, 0, LOCAL_MAXBUF);
|
|
memset(temp_buf, 0, LOCAL_MAXBUF);
|
|
|
|
memcpy(oldkey_buf, oldkey, SNMP_MIN(oldkey_len, properlength));
|
|
memcpy(newkey_buf, newkey, SNMP_MIN(newkey_len, properlength));
|
|
keychange_len = LOCAL_MAXBUF;
|
|
|
|
|
|
binary_to_hex(oldkey_buf, properlength, &s);
|
|
fprintf(stdout, "\noldkey%s (len=%d): %s\n",
|
|
(isdefault_old) ? " (default)" : "", properlength, s);
|
|
SNMP_FREE(s);
|
|
|
|
binary_to_hex(newkey_buf, properlength, &s);
|
|
fprintf(stdout, "newkey%s (len=%d): %s\n\n",
|
|
(isdefault_new) ? " (default)" : "", properlength, s);
|
|
SNMP_FREE(s);
|
|
|
|
|
|
rval = encode_keychange(hashtype, USM_LENGTH_OID_TRANSFORM,
|
|
oldkey_buf, properlength,
|
|
newkey_buf, properlength,
|
|
keychange_buf, &keychange_len);
|
|
FAILED(rval, "encode_keychange().");
|
|
|
|
if (keychange_len != (properlength * 2)) {
|
|
FAILED(SNMPERR_GENERR,
|
|
"KeyChange string (encoded) is not proper length "
|
|
"for this hash transform.");
|
|
}
|
|
|
|
binary_to_hex(keychange_buf, keychange_len, &s);
|
|
fprintf(stdout, "(%s) KeyChange string: %s\n\n",
|
|
((hashtype == usmHMACMD5AuthProtocol) ? "MD5" : "SHA"), s);
|
|
SNMP_FREE(s);
|
|
|
|
temp_len = properlength;
|
|
rval = decode_keychange(hashtype, USM_LENGTH_OID_TRANSFORM,
|
|
oldkey_buf, properlength,
|
|
keychange_buf, properlength * 2,
|
|
temp_buf, &temp_len);
|
|
FAILED(rval, "decode_keychange().");
|
|
|
|
if (temp_len != properlength) {
|
|
FAILED(SNMPERR_GENERR,
|
|
"decoded newkey is not proper length for "
|
|
"this hash transform.");
|
|
}
|
|
|
|
binary_to_hex(temp_buf, temp_len, &s);
|
|
fprintf(stdout, "decoded newkey: %s\n\n", s);
|
|
SNMP_FREE(s);
|
|
|
|
|
|
if (memcmp(newkey_buf, temp_buf, temp_len)) {
|
|
FAILED(SNMPERR_GENERR, "newkey did not decode properly.");
|
|
}
|
|
|
|
|
|
SUCCESS(hashname);
|
|
fprintf(stdout, "\n");
|
|
|
|
|
|
/*
|
|
* Multiplex different test combinations.
|
|
*
|
|
* First clause is for Test #2, second clause is for (last) Test #3.
|
|
*/
|
|
if (hashtype == usmHMACMD5AuthProtocol) {
|
|
hashtype = usmHMACSHA1AuthProtocol;
|
|
hashname = "usmHMACSHA1AuthProtocol (w/DES length kul's).";
|
|
properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES)
|
|
+ BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
|
|
goto test_keychange_again;
|
|
|
|
} else if (properlength < BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1)) {
|
|
hashtype = usmHMACSHA1AuthProtocol;
|
|
hashname = "usmHMACSHA1AuthProtocol.";
|
|
properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
|
|
goto test_keychange_again;
|
|
}
|
|
|
|
return failcount;
|
|
|
|
} /* end test_keychange() */
|