/*
*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation,
* YDC Corporation, IPA (Information-technology Promotion Agency, Japan).
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* conditions and disclaimer are agreed and accepted by the user:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of the copyrighters, the name of the project which
* is related to this software (hereinafter referred to as "project") nor
* the names of the contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. No merchantable use may be permitted without prior written
* notification to the copyrighters. However, using this software for the
* purpose of testing or evaluating any products including merchantable
* products may be permitted without any notification to the copyrighters.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
* BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT,STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $TAHI: v6eval/bin/prfcomp/prfcomp.c,v 1.2 2005/05/09 09:35:21 akisada Exp $
*
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <libgen.h>
#include <openssl/hmac.h>
typedef unsigned char bool;
const bool false = 0;
const bool true = 1;
static const unsigned char *prog = NULL;
int prfcomp_main(const unsigned char *const,
const unsigned char *const, const unsigned char *const);
bool hex_pton(const unsigned char *const, const unsigned int,
unsigned char *const, const unsigned int);
void prfcomp_dump(const unsigned char *const,
const unsigned char *const, const unsigned int,
const unsigned char *const, const unsigned int,
const unsigned char *const, const unsigned int);
void usage(void);
int
main(int argc, char **argv, char **envp)
{
const unsigned char *algorithm = NULL;
const unsigned char *key = NULL;
const unsigned char *msg = NULL;
if(!(prog = basename(argv[0]))) {
fprintf(stderr, "err: basename: %s -- %s\n",
strerror(errno), argv[0]);
return(-1);
/* NOTREACHED */
}
{
int ch = 0;
while((ch = getopt(argc, argv, "a:k:m:")) != -1) {
switch (ch) {
case 'a':
algorithm = optarg;
break;
case 'k':
key = optarg;
break;
case 'm':
msg = optarg;
break;
default:
usage();
/* NOTREACHED */
break;
}
}
argc -= optind;
argv += optind;
}
if(argc || (!(algorithm && key && msg))) {
usage();
/* NOTREACHED */
}
return(prfcomp_main(algorithm, key, msg));
/* NOTREACHED */
}
int
prfcomp_main(const unsigned char *const algorithm,
const unsigned char *const akey, const unsigned char *const msg)
{
const EVP_MD *evp_md = NULL;
unsigned char *key = NULL;
unsigned char *d = NULL;
unsigned int akey_len = strlen(akey);
unsigned int msg_len = strlen(msg);
unsigned int key_len = (akey_len + 1) / 2;
unsigned int n = (msg_len + 1) / 2;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int md_len = 0;
memset(md, 0, EVP_MAX_MD_SIZE);
for( ; ; ) {
if(!strcmp(algorithm, "hmacmd5")) {
evp_md = EVP_md5();
break;
}
if(!strcmp(algorithm, "hmacsha1")) {
evp_md = EVP_sha1();
break;
}
break;
}
if(!evp_md) {
fprintf(stderr, "err: algorithm: %s -- unknown algorithm\n",
algorithm);
return(-1);
}
if(!(key = malloc(key_len))) {
fprintf(stderr, "err: malloc: key: %s\n", strerror(errno));
return(-1);
}
if(!(d = malloc(n))) {
fprintf(stderr, "err: malloc: d: %s\n", strerror(errno));
return(-1);
}
memset(key, 0, key_len);
memset(d, 0, n);
if(!hex_pton(akey, akey_len, key, key_len)) {
fprintf(stderr, "err: HMAC: key: conversion failure -- %s\n",
akey);
return(-1);
}
if(!hex_pton(msg, msg_len, d, n)) {
fprintf(stderr, "err: HMAC: msg: conversion failure -- %s\n",
msg);
return(-1);
}
if(!HMAC(evp_md, key, key_len, d, n, md, &md_len)) {
fprintf(stderr, "err: HMAC: calculation failure\n");
return(-1);
}
prfcomp_dump(algorithm, key, key_len, d, n, md, md_len);
free(key);
free(d);
return(0);
}
bool
hex_pton(const unsigned char *const src, const unsigned int srclen,
unsigned char *const dst, const unsigned int dstlen)
{
bool upper = true;
unsigned int x = 0;
unsigned int y = 0;
const char xdigits_l[] = "0123456789abcdef";
const char xdigits_u[] = "0123456789ABCDEF";
const char *xdigits = 0;
memset(dst, 0, dstlen);
for( ; (x < srclen) && (y < dstlen); x ++) {
const char *cptr = 0;
if(((cptr = strchr((xdigits = xdigits_l), src[x])) == 0) &&
((cptr = strchr((xdigits = xdigits_u), src[x])) == 0)) {
return(false);
}
if(upper) {
dst[y] = (cptr - xdigits) << 4;
upper = false;
} else {
dst[y] |= (cptr - xdigits);
upper = true;
y ++;
}
}
return(true);
}
void
prfcomp_dump(const unsigned char *const algorithm,
const unsigned char *const key, const unsigned int key_len,
const unsigned char *const d, const unsigned int n,
const unsigned char *const md, const unsigned int md_len)
{
int x = 0;
printf("log:PRFComp_Results (length:%d)\n",
key_len + n + md_len);
printf("log:| algorithm = %s\n", algorithm);
printf("log:| Key (length:%d)\n", key_len);
printf("log:| | data = ");
for(x = 0; x < key_len; x ++) {
printf("%02x", key[x]);
}
printf("\n");
printf("log:| Message (length:%d)\n", n);
printf("log:| | data = ");
for(x = 0; x < n; x ++) {
printf("%02x", d[x]);
}
printf("\n");
printf("log:| Digest (length:%d)\n", md_len);
printf("log:| | data = ");
for(x = 0; x < md_len; x ++) {
printf("%02x", md[x]);
}
printf("\n");
return;
}
void
usage(void)
{
fprintf(stderr, "err: usage: %s -a algorithm -k key -m msg\n", prog);
fprintf(stderr, "err: \n");
fprintf(stderr, "err: algorithm: hmacmd5, hmacsha1\n");
fprintf(stderr, "err: \n");
exit(-1);
/* NOTREACHED */
return;
}
syntax highlighted by Code2HTML, v. 0.9.1