|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
* Copyright (C) 2003-2016 Free Software Foundation, Inc.
|
|
Packit |
aea12f |
* Copyright (C) 2015-2017 Red Hat, Inc.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This file is part of GnuTLS.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* GnuTLS is free software: you can redistribute it and/or modify it
|
|
Packit |
aea12f |
* under the terms of the GNU General Public License as published by
|
|
Packit |
aea12f |
* the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
aea12f |
* (at your option) any later version.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* GnuTLS is distributed in the hope that it will be useful, but
|
|
Packit |
aea12f |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
aea12f |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
aea12f |
* General Public License for more details.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* You should have received a copy of the GNU General Public License
|
|
Packit |
aea12f |
* along with this program. If not, see
|
|
Packit |
aea12f |
* <https://www.gnu.org/licenses/>.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#include <config.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#include <gnutls/gnutls.h>
|
|
Packit |
aea12f |
#include <gnutls/x509.h>
|
|
Packit |
aea12f |
#include <gnutls/openpgp.h>
|
|
Packit |
aea12f |
#include <gnutls/pkcs12.h>
|
|
Packit |
aea12f |
#include <gnutls/pkcs11.h>
|
|
Packit |
aea12f |
#include <gnutls/abstract.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#include <stdio.h>
|
|
Packit |
aea12f |
#include <stdlib.h>
|
|
Packit |
aea12f |
#include <string.h>
|
|
Packit |
aea12f |
#include <ctype.h>
|
|
Packit |
aea12f |
#include <time.h>
|
|
Packit |
aea12f |
#include <unistd.h>
|
|
Packit |
aea12f |
#include <errno.h>
|
|
Packit |
aea12f |
#include <sys/types.h>
|
|
Packit |
aea12f |
#include <sys/stat.h>
|
|
Packit |
aea12f |
#include <fcntl.h>
|
|
Packit |
aea12f |
#include <common.h>
|
|
Packit |
aea12f |
#include "certtool-common.h"
|
|
Packit |
aea12f |
#include "certtool-args.h"
|
|
Packit |
aea12f |
#include "certtool-cfg.h"
|
|
Packit |
aea12f |
#include "common.h"
|
|
Packit |
aea12f |
#include <minmax.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Gnulib portability files. */
|
|
Packit |
aea12f |
#include <read-file.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
unsigned char *lbuffer = NULL;
|
|
Packit |
aea12f |
unsigned long lbuffer_size = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static unsigned long file_size(FILE *fp)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned long size;
|
|
Packit |
aea12f |
long cur = ftell(fp);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (cur == -1)
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (fseek(fp, 0, SEEK_END) == -1)
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = ftell(fp);
|
|
Packit |
aea12f |
if (fseek(fp, cur, SEEK_SET) == -1) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error reading file size\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
return size;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void fix_lbuffer(unsigned long size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (lbuffer_size == 0 || lbuffer == NULL) {
|
|
Packit |
aea12f |
if (size == 0)
|
|
Packit |
aea12f |
lbuffer_size = 64*1024;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
lbuffer_size = MAX(64*1024,size+1);
|
|
Packit |
aea12f |
lbuffer = malloc(lbuffer_size);
|
|
Packit |
aea12f |
} else if (size > lbuffer_size) {
|
|
Packit |
aea12f |
lbuffer_size = MAX(64*1024,size+1);
|
|
Packit |
aea12f |
lbuffer = realloc(lbuffer, lbuffer_size);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (lbuffer == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "memory error");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
FILE *safe_open_rw(const char *file, int privkey_op)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
mode_t omask = 0;
|
|
Packit |
aea12f |
FILE *fh;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (privkey_op != 0) {
|
|
Packit |
aea12f |
omask = umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fh = fopen(file, "wb");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (privkey_op != 0) {
|
|
Packit |
aea12f |
umask(omask);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return fh;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_datum_t *load_secret_key(int mand, common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
static char raw_key[64];
|
|
Packit |
aea12f |
size_t raw_key_size = sizeof(raw_key);
|
|
Packit |
aea12f |
static gnutls_datum_t key;
|
|
Packit |
aea12f |
gnutls_datum_t hex_key;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->verbose)
|
|
Packit |
aea12f |
fprintf(stderr, "Loading secret key...\n");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->secret_key == NULL) {
|
|
Packit |
aea12f |
if (mand) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --secret-key\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
} else
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
hex_key.data = (void *) info->secret_key;
|
|
Packit |
aea12f |
hex_key.size = strlen(info->secret_key);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_hex_decode(&hex_key, raw_key, &raw_key_size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "hex_decode: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
key.data = (void *) raw_key;
|
|
Packit |
aea12f |
key.size = raw_key_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return &ke;;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
const char *get_password(common_info_st * cinfo, unsigned int *flags,
|
|
Packit |
aea12f |
int confirm)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
const char *p;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (cinfo->null_password) {
|
|
Packit |
aea12f |
if (flags)
|
|
Packit |
aea12f |
*flags |= GNUTLS_PKCS_NULL_PASSWORD;
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
} else if (cinfo->password) {
|
|
Packit |
aea12f |
p = cinfo->password;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
if (confirm)
|
|
Packit |
aea12f |
p = get_confirmed_pass(true);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
p = get_pass();
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((p == NULL || p[0] == 0) && flags && !cinfo->empty_password)
|
|
Packit |
aea12f |
*flags |= GNUTLS_PKCS_PLAIN;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return p;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static gnutls_privkey_t _load_privkey(gnutls_datum_t * dat,
|
|
Packit |
aea12f |
common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_privkey_t key;
|
|
Packit |
aea12f |
unsigned int flags = 0;
|
|
Packit |
aea12f |
const char *pass;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_privkey_init(&key);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "privkey_init: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_privkey_import_x509_raw(key, dat, info->incert_format,
|
|
Packit |
aea12f |
NULL, 0);
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_DECRYPTION_FAILED) {
|
|
Packit |
aea12f |
pass = get_password(info, &flags, 0);
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_privkey_import_x509_raw(key, dat,
|
|
Packit |
aea12f |
info->incert_format,
|
|
Packit |
aea12f |
pass, flags);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"import error: could not find a valid PEM header; "
|
|
Packit |
aea12f |
"check if your key is PKCS #12 encoded\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "error loading file at --load-privkey: %s: %s\n",
|
|
Packit |
aea12f |
info->privkey, gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return key;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static gnutls_privkey_t _load_url_privkey(const char *url)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_privkey_t key;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_privkey_init(&key);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "privkey_init: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_privkey_import_url(key, url, 0);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "error importing key at %s: %s\n",
|
|
Packit |
aea12f |
url, gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return key;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static gnutls_pubkey_t _load_url_pubkey(const char *url)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_pubkey_t pubkey;
|
|
Packit |
aea12f |
unsigned int obj_flags = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_pubkey_init(&pubkey);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_pubkey_import_url(pubkey, url, obj_flags);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error in %s:%d: %s: %s\n", __func__,
|
|
Packit |
aea12f |
__LINE__, gnutls_strerror(ret), url);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return pubkey;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Load the private key.
|
|
Packit |
aea12f |
* @mand should be non zero if it is required to read a private key.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_privkey_t load_private_key(int mand, common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_privkey_t key;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!info->privkey && !mand)
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->privkey == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --load-privkey\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (gnutls_url_is_supported(info->privkey) != 0)
|
|
Packit |
aea12f |
return _load_url_privkey(info->privkey);
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
dat.data = (void *) read_file(info->privkey, RF_BINARY, &size);
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!dat.data) {
|
|
Packit |
aea12f |
fprintf(stderr, "error reading file at --load-privkey: %s\n",
|
|
Packit |
aea12f |
info->privkey);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
key = _load_privkey(&dat, info);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
free(dat.data);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return key;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Load the private key.
|
|
Packit |
aea12f |
* @mand should be non zero if it is required to read a private key.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_x509_privkey_t
|
|
Packit |
aea12f |
load_x509_private_key(int mand, common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_x509_privkey_t key;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
unsigned int flags = 0;
|
|
Packit |
aea12f |
const char *pass;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!info->privkey && !mand)
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->privkey == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --load-privkey\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_init(&key);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "privkey_init: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
dat.data = (void *) read_file(info->privkey, RF_BINARY, &size);
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!dat.data) {
|
|
Packit |
aea12f |
fprintf(stderr, "error reading file at --load-privkey: %s\n",
|
|
Packit |
aea12f |
info->privkey);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->pkcs8) {
|
|
Packit |
aea12f |
pass = get_password(info, &flags, 0);
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_import_pkcs8(key, &dat,
|
|
Packit |
aea12f |
info->incert_format,
|
|
Packit |
aea12f |
pass, flags);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_import2(key, &dat,
|
|
Packit |
aea12f |
info->incert_format, NULL,
|
|
Packit |
aea12f |
0);
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_DECRYPTION_FAILED) {
|
|
Packit |
aea12f |
pass = get_password(info, &flags, 0);
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_import2(key, &dat,
|
|
Packit |
aea12f |
info->
|
|
Packit |
aea12f |
incert_format,
|
|
Packit |
aea12f |
pass, flags);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
free(dat.data);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"import error: could not find a valid PEM header; "
|
|
Packit |
aea12f |
"check if your key is PEM encoded\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "error importing private key: %s: %s\n",
|
|
Packit |
aea12f |
info->privkey, gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return key;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Loads the certificate
|
|
Packit |
aea12f |
* If mand is non zero then a certificate is mandatory. Otherwise
|
|
Packit |
aea12f |
* null will be returned if the certificate loading fails.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_x509_crt_t load_cert(int mand, common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_x509_crt_t *crt;
|
|
Packit |
aea12f |
gnutls_x509_crt_t ret_crt;
|
|
Packit |
aea12f |
size_t size, i;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
crt = load_cert_list(mand, &size, info);
|
|
Packit |
aea12f |
if (crt) {
|
|
Packit |
aea12f |
ret_crt = crt[0];
|
|
Packit |
aea12f |
for (i=1;i
|
|
Packit |
aea12f |
gnutls_x509_crt_deinit(crt[i]);
|
|
Packit |
aea12f |
gnutls_free(crt);
|
|
Packit |
aea12f |
return ret_crt;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Loads a certificate list
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_x509_crt_t *load_cert_list(int mand, size_t * crt_size,
|
|
Packit |
aea12f |
common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit Service |
991b93 |
FILE *fp;
|
|
Packit |
aea12f |
static gnutls_x509_crt_t *crt;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
unsigned size;
|
|
Packit |
aea12f |
unsigned int crt_max;
|
|
Packit |
aea12f |
unsigned flags = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crt_size = 0;
|
|
Packit |
aea12f |
if (info->verbose)
|
|
Packit |
aea12f |
fprintf(stderr, "Loading certificate list...\n");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->cert == NULL) {
|
|
Packit |
aea12f |
if (mand) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --load-certificate\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
} else
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
fp = fopen(info->cert, "r");
|
|
Packit Service |
991b93 |
if (fp == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "Could not open %s\n", info->cert);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
fix_lbuffer(file_size(fp));
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
size = fread(lbuffer, 1, lbuffer_size - 1, fp);
|
|
Packit |
aea12f |
lbuffer[size] = 0;
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
fclose(fp);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
dat.data = (void *) lbuffer;
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->sort_chain)
|
|
Packit |
aea12f |
flags |= GNUTLS_X509_CRT_LIST_SORT;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crt_list_import2(&crt, &crt_max, &dat, GNUTLS_X509_FMT_PEM, flags);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error loading certificates: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crt_size = crt_max;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->verbose)
|
|
Packit |
aea12f |
fprintf(stderr, "Loaded %d certificates.\n",
|
|
Packit |
aea12f |
(int) crt_max);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return crt;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Loads a CRL list
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_x509_crl_t *load_crl_list(int mand, size_t * crl_size,
|
|
Packit |
aea12f |
common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit Service |
991b93 |
FILE *fp;
|
|
Packit |
aea12f |
static gnutls_x509_crl_t *crl;
|
|
Packit |
aea12f |
unsigned int crl_max;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crl_size = 0;
|
|
Packit |
aea12f |
if (info->verbose)
|
|
Packit |
aea12f |
fprintf(stderr, "Loading CRL list...\n");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->crl == NULL) {
|
|
Packit |
aea12f |
if (mand) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --load-crl\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
} else
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
fp = fopen(info->crl, "r");
|
|
Packit Service |
991b93 |
if (fp == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "Could not open %s\n", info->crl);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
fix_lbuffer(file_size(fp));
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
size = fread(lbuffer, 1, lbuffer_size - 1, fp);
|
|
Packit |
aea12f |
lbuffer[size] = 0;
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
fclose(fp);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
dat.data = (void *) lbuffer;
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crl_list_import2(&crl, &crl_max, &dat, GNUTLS_X509_FMT_PEM, 0);
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_BASE64_DECODING_ERROR) {
|
|
Packit |
aea12f |
ret = gnutls_x509_crl_list_import2(&crl, &crl_max, &dat, GNUTLS_X509_FMT_DER, 0);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error loading CRLs: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crl_size = crl_max;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->verbose)
|
|
Packit |
aea12f |
fprintf(stderr, "Loaded %d CRLs.\n",
|
|
Packit |
aea12f |
(int) *crl_size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return crl;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Load the Certificate Request.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_x509_crq_t load_request(common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_x509_crq_t crq;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!info->request)
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crq_init(&crq;;
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "crq_init: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
dat.data = (void *) read_file(info->request, RF_BINARY, &size);
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!dat.data) {
|
|
Packit |
aea12f |
fprintf(stderr, "error reading file at --load-request: %s\n",
|
|
Packit |
aea12f |
info->request);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crq_import(crq, &dat, info->incert_format);
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"import error: could not find a valid PEM header\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
free(dat.data);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "error importing certificate request: %s: %s\n",
|
|
Packit |
aea12f |
info->request, gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
return crq;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Load the CA's private key.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_privkey_t load_ca_private_key(common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_privkey_t key;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->ca_privkey == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --load-ca-privkey\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (gnutls_url_is_supported(info->ca_privkey) != 0)
|
|
Packit |
aea12f |
return _load_url_privkey(info->ca_privkey);
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
dat.data = (void *) read_file(info->ca_privkey, RF_BINARY, &size);
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!dat.data) {
|
|
Packit |
aea12f |
fprintf(stderr, "error reading file at --load-ca-privkey: %s\n",
|
|
Packit |
aea12f |
info->ca_privkey);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
key = _load_privkey(&dat, info);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
free(dat.data);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return key;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Loads the CA's certificate
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_x509_crt_t load_ca_cert(unsigned mand, common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_x509_crt_t crt;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (mand == 0 && info->ca == NULL) {
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->ca == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --load-ca-certificate\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crt_init(&crt;;
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "crt_init: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (gnutls_url_is_supported(info->ca) != 0) {
|
|
Packit |
aea12f |
ret = gnutls_x509_crt_import_url(crt, info->ca, 0);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "error importing CA certificate: %s: %s\n",
|
|
Packit |
aea12f |
info->ca, gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
return crt;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
dat.data = (void *) read_file(info->ca, RF_BINARY, &size);
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!dat.data) {
|
|
Packit |
aea12f |
fprintf(stderr, "error reading file at --load-ca-certificate: %s\n",
|
|
Packit |
aea12f |
info->ca);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crt_import(crt, &dat, info->incert_format);
|
|
Packit |
aea12f |
free(dat.data);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "error importing CA certificate: %s: %s\n",
|
|
Packit |
aea12f |
info->ca, gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return crt;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Load a public key.
|
|
Packit |
aea12f |
* @mand should be non zero if it is required to read a public key.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
gnutls_pubkey_t load_pubkey(int mand, common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_pubkey_t key;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t dat;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!info->pubkey && !mand)
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->pubkey == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "missing --load-pubkey\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (gnutls_url_is_supported(info->pubkey) != 0)
|
|
Packit |
aea12f |
return _load_url_pubkey(info->pubkey);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_pubkey_init(&key);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "privkey_init: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
dat.data = (void *) read_file(info->pubkey, RF_BINARY, &size);
|
|
Packit |
aea12f |
dat.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!dat.data) {
|
|
Packit |
aea12f |
fprintf(stderr, "error reading file at --load-pubkey: %s\n", info->pubkey);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_pubkey_import(key, &dat, info->incert_format);
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
|
|
Packit |
aea12f |
ret = gnutls_pubkey_import_x509_raw(key, &dat, info->incert_format, 0);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"import error: could not find a valid PEM header; "
|
|
Packit |
aea12f |
"check if your key has the PUBLIC KEY header\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
} else if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "importing public key: %s: %s\n",
|
|
Packit |
aea12f |
info->pubkey, gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
free(dat.data);
|
|
Packit |
aea12f |
return key;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_pubkey_t load_public_key_or_import(int mand,
|
|
Packit |
aea12f |
gnutls_privkey_t privkey,
|
|
Packit |
aea12f |
common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_pubkey_t pubkey;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_pubkey_init(&pubkey);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "gnutls_pubkey_init: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!privkey || (ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0)) < 0) { /* could not get (e.g. on PKCS #11 */
|
|
Packit |
aea12f |
gnutls_pubkey_deinit(pubkey);
|
|
Packit |
aea12f |
pubkey = load_pubkey(0, info);
|
|
Packit |
aea12f |
if (pubkey == NULL && mand) {
|
|
Packit |
aea12f |
fprintf(stderr, "Could not determine the public key for the operation.\nYou must specify --load-privkey or --load-pubkey if missing.\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return pubkey;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static const char *bits_to_sp(gnutls_pk_algorithm_t pk, unsigned int bits)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_sec_param_t s = gnutls_pk_bits_to_sec_param(pk, bits);
|
|
Packit |
aea12f |
if (s == GNUTLS_SEC_PARAM_UNKNOWN) {
|
|
Packit |
aea12f |
return gnutls_sec_param_get_name(GNUTLS_SEC_PARAM_MEDIUM);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return gnutls_sec_param_get_name(s);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
get_bits(gnutls_pk_algorithm_t key_type, int info_bits,
|
|
Packit |
aea12f |
const char *info_sec_param, int warn)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int bits;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info_bits != 0) {
|
|
Packit |
aea12f |
static int warned = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (warned == 0 && warn != 0 && GNUTLS_BITS_ARE_CURVE(info_bits)==0) {
|
|
Packit |
aea12f |
warned = 1;
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"** Note: You may use '--sec-param %s' instead of '--bits %d'\n",
|
|
Packit |
aea12f |
bits_to_sp(key_type, info_bits), info_bits);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
bits = info_bits;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
if (info_sec_param == 0) {
|
|
Packit |
aea12f |
/* For ECDSA keys use 256 bits or better, as they are widely supported */
|
|
Packit |
aea12f |
info_sec_param = "HIGH";
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
bits =
|
|
Packit |
aea12f |
gnutls_sec_param_to_pk_bits(key_type,
|
|
Packit |
aea12f |
str_to_sec_param
|
|
Packit |
aea12f |
(info_sec_param));
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return bits;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_sec_param_t str_to_sec_param(const char *str)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (strcasecmp(str, "low") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_SEC_PARAM_LOW;
|
|
Packit |
aea12f |
} else if (strcasecmp(str, "legacy") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_SEC_PARAM_LEGACY;
|
|
Packit |
aea12f |
} else if (strcasecmp(str, "normal") == 0 || strcasecmp(str, "medium") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_SEC_PARAM_MEDIUM;
|
|
Packit |
aea12f |
} else if (strcasecmp(str, "high") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_SEC_PARAM_HIGH;
|
|
Packit |
aea12f |
} else if (strcasecmp(str, "ultra") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_SEC_PARAM_ULTRA;
|
|
Packit |
aea12f |
} else if (strcasecmp(str, "future") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_SEC_PARAM_FUTURE;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fprintf(stderr, "Unknown security parameter string: %s\n",
|
|
Packit |
aea12f |
str);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#define SPACE "\t"
|
|
Packit |
aea12f |
static void
|
|
Packit |
aea12f |
print_hex_datum(FILE * outfile, gnutls_datum_t * dat, int cprint)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned int j;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (cprint != 0) {
|
|
Packit |
aea12f |
fprintf(outfile, "\n" SPACE "\"");
|
|
Packit |
aea12f |
for (j = 0; j < dat->size; j++) {
|
|
Packit |
aea12f |
fprintf(outfile, "\\x%.2x",
|
|
Packit |
aea12f |
(unsigned char) dat->data[j]);
|
|
Packit |
aea12f |
if ((j + 1) % 16 == 0) {
|
|
Packit |
aea12f |
fprintf(outfile, "\"\n" SPACE "\"");
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
fprintf(outfile, "\";\n\n");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(outfile, "\n" SPACE);
|
|
Packit |
aea12f |
for (j = 0; j < dat->size; j++) {
|
|
Packit |
aea12f |
if ((j + 1) % 16 == 0) {
|
|
Packit |
aea12f |
fprintf(outfile, "%.2x", (unsigned char) dat->data[j]);
|
|
Packit |
aea12f |
fprintf(outfile, "\n" SPACE);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fprintf(outfile, "%.2x:", (unsigned char) dat->data[j]);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
fprintf(outfile, "\n\n");
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static void print_head(FILE * out, const char *txt, unsigned int size,
|
|
Packit |
aea12f |
int cprint)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned i;
|
|
Packit |
aea12f |
char *p, *ntxt;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (cprint != 0) {
|
|
Packit |
aea12f |
if (size > 0)
|
|
Packit |
aea12f |
ret = asprintf(&ntxt, "const unsigned char %s[%u] =",
|
|
Packit |
aea12f |
txt, size);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
ret = asprintf(&ntxt, "const unsigned char %s[] =\n",
|
|
Packit |
aea12f |
txt);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret == -1) {
|
|
Packit |
aea12f |
fprintf(stderr, "memory error\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
p = strstr(ntxt, "char");
|
|
Packit |
aea12f |
p += 5;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
for (i = 0; i < strlen(txt); i++)
|
|
Packit |
aea12f |
if (p[i] == ' ')
|
|
Packit |
aea12f |
p[i] = '_';
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(out, "%s", ntxt);
|
|
Packit |
aea12f |
free(ntxt);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
fprintf(out, "%s:", txt);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void
|
|
Packit |
aea12f |
print_dsa_pkey(FILE * outfile, gnutls_datum_t * x, gnutls_datum_t * y,
|
|
Packit |
aea12f |
gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * g,
|
|
Packit |
aea12f |
int cprint)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (x) {
|
|
Packit |
aea12f |
print_head(outfile, "private key", x->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, x, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
print_head(outfile, "public key", y->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, y, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "p", p->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, p, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "q", q->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, q, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "g", g->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, g, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_ecc_curve_t str_to_curve(const char *str)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned num = 0;
|
|
Packit |
aea12f |
const gnutls_ecc_curve_t *list, *p;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
list = gnutls_ecc_curve_list();
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
p = list;
|
|
Packit |
aea12f |
while(*p != 0) {
|
|
Packit |
aea12f |
if (strcasecmp(str, gnutls_ecc_curve_get_name(*p)) == 0)
|
|
Packit |
aea12f |
return *p;
|
|
Packit |
aea12f |
p++;
|
|
Packit |
aea12f |
num++;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(stderr, "Unsupported curve: %s\nAvailable curves:\n", str);
|
|
Packit |
aea12f |
if (num == 0)
|
|
Packit |
aea12f |
printf("none\n");
|
|
Packit |
aea12f |
p = list;
|
|
Packit |
aea12f |
while(*p != 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "\t- %s\n",
|
|
Packit |
aea12f |
gnutls_ecc_curve_get_name(*p));
|
|
Packit |
aea12f |
p++;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void
|
|
Packit |
aea12f |
print_ecc_pkey(FILE * outfile, gnutls_ecc_curve_t curve,
|
|
Packit |
aea12f |
gnutls_datum_t * k, gnutls_datum_t * x, gnutls_datum_t * y,
|
|
Packit |
aea12f |
int cprint)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (cprint != 0)
|
|
Packit |
aea12f |
fprintf(outfile, "/* curve: %s */\n",
|
|
Packit |
aea12f |
gnutls_ecc_curve_get_name(curve));
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
fprintf(outfile, "curve:\t%s\n",
|
|
Packit |
aea12f |
gnutls_ecc_curve_get_name(curve));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (k && k->data) {
|
|
Packit |
aea12f |
print_head(outfile, "private key", k->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, k, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (x && x->data) {
|
|
Packit |
aea12f |
print_head(outfile, "x", x->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, x, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (y && y->data) {
|
|
Packit |
aea12f |
print_head(outfile, "y", y->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, y, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static void reverse_datum(gnutls_datum_t *d)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned int i;
|
|
Packit |
aea12f |
unsigned char c;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
for (i = 0; i < d->size / 2; i++) {
|
|
Packit |
aea12f |
c = d->data[i];
|
|
Packit |
aea12f |
d->data[i] = d->data[d->size - i - 1];
|
|
Packit |
aea12f |
d->data[d->size - i - 1] = c;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void
|
|
Packit |
aea12f |
print_gost_pkey(FILE * outfile, gnutls_ecc_curve_t curve,
|
|
Packit |
aea12f |
gnutls_digest_algorithm_t digest, gnutls_gost_paramset_t paramset,
|
|
Packit |
aea12f |
gnutls_datum_t * k, gnutls_datum_t * x, gnutls_datum_t * y,
|
|
Packit |
aea12f |
int cprint)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (cprint != 0)
|
|
Packit |
aea12f |
fprintf(outfile, "/* curve: %s */\n",
|
|
Packit |
aea12f |
gnutls_ecc_curve_get_name(curve));
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
fprintf(outfile, "curve:\t%s\n",
|
|
Packit |
aea12f |
gnutls_ecc_curve_get_name(curve));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (cprint != 0)
|
|
Packit |
aea12f |
fprintf(outfile, "/* digest: %s */\n",
|
|
Packit |
aea12f |
gnutls_digest_get_name(digest));
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
fprintf(outfile, "digest:\t%s\n",
|
|
Packit |
aea12f |
gnutls_digest_get_name(digest));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (cprint != 0)
|
|
Packit |
aea12f |
fprintf(outfile, "/* paramset: %s */\n",
|
|
Packit |
aea12f |
gnutls_gost_paramset_get_name(paramset));
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
fprintf(outfile, "paramset:\t%s\n",
|
|
Packit |
aea12f |
gnutls_gost_paramset_get_name(paramset));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (k) {
|
|
Packit |
aea12f |
reverse_datum(k);
|
|
Packit |
aea12f |
print_head(outfile, "private key", k->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, k, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
reverse_datum(x);
|
|
Packit |
aea12f |
reverse_datum(y);
|
|
Packit |
aea12f |
print_head(outfile, "x", x->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, x, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "y", y->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, y, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void
|
|
Packit |
aea12f |
print_rsa_pkey(FILE * outfile, gnutls_datum_t * m, gnutls_datum_t * e,
|
|
Packit |
aea12f |
gnutls_datum_t * d, gnutls_datum_t * p, gnutls_datum_t * q,
|
|
Packit |
aea12f |
gnutls_datum_t * u, gnutls_datum_t * exp1,
|
|
Packit |
aea12f |
gnutls_datum_t * exp2, int cprint)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
print_head(outfile, "modulus", m->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, m, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "public exponent", e->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, e, cprint);
|
|
Packit |
aea12f |
if (d) {
|
|
Packit |
aea12f |
print_head(outfile, "private exponent", d->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, d, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "prime1", p->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, p, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "prime2", q->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, q, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "coefficient", u->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, u, cprint);
|
|
Packit |
aea12f |
if (exp1 && exp2) {
|
|
Packit |
aea12f |
print_head(outfile, "exp1", exp1->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, exp1, cprint);
|
|
Packit |
aea12f |
print_head(outfile, "exp2", exp2->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, exp2, cprint);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void print_pubkey_info(gnutls_pubkey_t pubkey,
|
|
Packit |
aea12f |
FILE *outfile,
|
|
Packit |
aea12f |
gnutls_certificate_print_formats_t format,
|
|
Packit |
aea12f |
gnutls_x509_crt_fmt_t outcert_format,
|
|
Packit |
aea12f |
unsigned int outtext)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_datum_t data;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (outtext) {
|
|
Packit |
aea12f |
ret = gnutls_pubkey_print(pubkey, format, &data);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "pubkey_print error: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(outfile, "%s\n\n", data.data);
|
|
Packit |
aea12f |
gnutls_free(data.data);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fix_lbuffer(0);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = lbuffer_size;
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_pubkey_export(pubkey, outcert_format, lbuffer,
|
|
Packit |
aea12f |
&size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "export error: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fwrite(lbuffer, 1, size, outfile);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static void
|
|
Packit |
aea12f |
print_dh_info(FILE * outfile, gnutls_datum_t * p, gnutls_datum_t * g,
|
|
Packit |
aea12f |
unsigned int q_bits, int cprint)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (q_bits > 0) {
|
|
Packit |
aea12f |
if (cprint != 0)
|
|
Packit |
aea12f |
fprintf(outfile,
|
|
Packit |
aea12f |
"\n /* recommended key length: %d bytes */\n\n",
|
|
Packit |
aea12f |
(7 + q_bits) / 8);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
fprintf(outfile,
|
|
Packit |
aea12f |
"\nRecommended key length: %d bits\n\n",
|
|
Packit |
aea12f |
q_bits);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
print_head(outfile, "generator", g->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, g, cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
print_head(outfile, "prime", p->size, cprint);
|
|
Packit |
aea12f |
print_hex_datum(outfile, p, cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static
|
|
Packit |
aea12f |
int import_dsa_dh(gnutls_dh_params_t dh_params, gnutls_datum_t *params, gnutls_x509_crt_fmt_t format)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_x509_privkey_t pkey;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_init(&pkey);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_import(pkey, params, format);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_dh_params_import_dsa(dh_params, pkey);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_x509_privkey_deinit(pkey);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void dh_info(FILE * infile, FILE * outfile, common_info_st * ci)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_datum_t params;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
int ret, ret2;
|
|
Packit |
aea12f |
gnutls_dh_params_t dh_params;
|
|
Packit |
aea12f |
gnutls_datum_t p, g;
|
|
Packit |
aea12f |
unsigned int q_bits = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fix_lbuffer(0);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (gnutls_dh_params_init(&dh_params) < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error in dh parameter initialization\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
params.data = (void *) fread_file(infile, 0, &size);
|
|
Packit |
aea12f |
params.size = size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (params.data == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "Could not read input\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_dh_params_import_pkcs3(dh_params, ¶ms,
|
|
Packit |
aea12f |
ci->incert_format);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
/* Try DSA */
|
|
Packit |
aea12f |
ret2 = import_dsa_dh(dh_params, ¶ms, ci->incert_format);
|
|
Packit |
aea12f |
if (ret2 < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error parsing dh params: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_dh_params_export_raw(dh_params, &p, &g, &q_bits);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error exporting parameters: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ci->outtext)
|
|
Packit |
aea12f |
print_dh_info(outfile, &p, &g, q_bits, ci->cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!ci->cprint) { /* generate a PKCS#3 structure */
|
|
Packit |
aea12f |
size_t len = lbuffer_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_dh_params_export_pkcs3(dh_params,
|
|
Packit |
aea12f |
ci->outcert_format,
|
|
Packit |
aea12f |
lbuffer, &len;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret == 0) {
|
|
Packit |
aea12f |
if (ci->outcert_format == GNUTLS_X509_FMT_PEM) {
|
|
Packit |
aea12f |
fprintf(outfile, "\n%s", lbuffer);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fwrite(lbuffer, 1, len, outfile);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fprintf(stderr, "Error: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(p.data);
|
|
Packit |
aea12f |
gnutls_free(g.data);
|
|
Packit |
aea12f |
gnutls_dh_params_deinit(dh_params);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int cipher_to_flags(const char *cipher)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (cipher == NULL) {
|
|
Packit |
aea12f |
#ifdef ENABLE_FIPS140
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_AES_128;
|
|
Packit |
aea12f |
#else /* compatibility mode - most implementations don't support PBES2 with AES */
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PKCS12_3DES;
|
|
Packit |
aea12f |
#endif
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "3des") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_3DES;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "3des-pkcs12") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PKCS12_3DES;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "arcfour") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PKCS12_ARCFOUR;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "aes-128") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_AES_128;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "aes-192") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_AES_192;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "aes-256") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_AES_256;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "rc2-40") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PKCS12_RC2_40;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "gost28147-tc26z") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_GOST_TC26Z;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "gost28147-cpa") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_GOST_CPA;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "gost28147-cpb") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_GOST_CPB;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "gost28147-cpc") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_GOST_CPC;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "gost28147-cpd") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_USE_PBES2_GOST_CPD;
|
|
Packit |
aea12f |
} else if (strcasecmp(cipher, "none") == 0) {
|
|
Packit |
aea12f |
return GNUTLS_PKCS_PLAIN;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(stderr, "unknown cipher %s\n", cipher);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static void privkey_info_int(FILE *outfile, common_info_st * cinfo,
|
|
Packit |
aea12f |
gnutls_x509_privkey_t key)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret, key_type;
|
|
Packit |
aea12f |
unsigned int bits = 0;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
const char *cprint;
|
|
Packit |
aea12f |
gnutls_x509_spki_t spki;
|
|
Packit |
aea12f |
gnutls_digest_algorithm_t dig;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Public key algorithm
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
fprintf(outfile, "Public Key Info:\n");
|
|
Packit |
aea12f |
ret = gnutls_x509_spki_init(&spki);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "spki_init: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
return;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(outfile, "\tPublic Key Algorithm: ");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
key_type = gnutls_x509_privkey_get_pk_algorithm2(key, &bits);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
cprint = gnutls_pk_algorithm_get_name(key_type);
|
|
Packit |
aea12f |
fprintf(outfile, "%s\n", cprint ? cprint : "Unknown");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (key_type == GNUTLS_PK_RSA_PSS) {
|
|
Packit |
aea12f |
unsigned int salt_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_get_spki(key, spki, 0);
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
|
Packit |
aea12f |
goto spki_skip;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "spki_get: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
goto spki_skip;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_spki_get_rsa_pss_params(spki, &dig, &salt_size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "spki_get_rsa_pss_params: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fprintf(outfile, "\t\tHash Algorithm: %s\n",
|
|
Packit |
aea12f |
gnutls_digest_get_name(dig));
|
|
Packit |
aea12f |
fprintf(outfile, "\t\tSalt Length: %d\n", salt_size);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
spki_skip:
|
|
Packit |
aea12f |
gnutls_x509_spki_deinit(spki);
|
|
Packit |
aea12f |
fprintf(outfile, "\tKey Security Level: %s (%u bits)\n\n",
|
|
Packit |
aea12f |
gnutls_sec_param_get_name(gnutls_x509_privkey_sec_param
|
|
Packit |
aea12f |
(key)), bits);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Print the raw public and private keys
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
if (GNUTLS_PK_IS_RSA(key_type)) {
|
|
Packit |
aea12f |
gnutls_datum_t m, e, d, p, q, u, exp1, exp2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_export_rsa_raw2(key, &m, &e, &d,
|
|
Packit |
aea12f |
&p, &q, &u, &exp1,
|
|
Packit |
aea12f |
&exp2;;
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error in key RSA data export: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
else {
|
|
Packit |
aea12f |
print_rsa_pkey(outfile, &m, &e, &d, &p, &q, &u,
|
|
Packit |
aea12f |
&exp1, &exp2, cinfo->cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(m.data);
|
|
Packit |
aea12f |
gnutls_free(e.data);
|
|
Packit |
aea12f |
gnutls_free(d.data);
|
|
Packit |
aea12f |
gnutls_free(p.data);
|
|
Packit |
aea12f |
gnutls_free(q.data);
|
|
Packit |
aea12f |
gnutls_free(u.data);
|
|
Packit |
aea12f |
gnutls_free(exp1.data);
|
|
Packit |
aea12f |
gnutls_free(exp2.data);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
} else if (key_type == GNUTLS_PK_DSA) {
|
|
Packit |
aea12f |
gnutls_datum_t p, q, g, y, x;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_export_dsa_raw(key, &p, &q, &g, &y,
|
|
Packit |
aea12f |
&x);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error in key DSA data export: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
else {
|
|
Packit |
aea12f |
print_dsa_pkey(outfile, &x, &y, &p, &q, &g,
|
|
Packit |
aea12f |
cinfo->cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(x.data);
|
|
Packit |
aea12f |
gnutls_free(y.data);
|
|
Packit |
aea12f |
gnutls_free(p.data);
|
|
Packit |
aea12f |
gnutls_free(q.data);
|
|
Packit |
aea12f |
gnutls_free(g.data);
|
|
Packit |
aea12f |
}
|
|
Packit Service |
991b93 |
} else if (key_type == GNUTLS_PK_ECDSA ||
|
|
Packit Service |
991b93 |
key_type == GNUTLS_PK_EDDSA_ED25519 ||
|
|
Packit Service |
991b93 |
key_type == GNUTLS_PK_EDDSA_ED448) {
|
|
Packit |
aea12f |
gnutls_datum_t y, x, k;
|
|
Packit |
aea12f |
gnutls_ecc_curve_t curve;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_export_ecc_raw(key, &curve, &x, &y,
|
|
Packit |
aea12f |
&k);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error in key ECC data export: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
else {
|
|
Packit |
aea12f |
print_ecc_pkey(outfile, curve, &k, &x, &y,
|
|
Packit |
aea12f |
cinfo->cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(x.data);
|
|
Packit |
aea12f |
gnutls_free(y.data);
|
|
Packit |
aea12f |
gnutls_free(k.data);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
} else if (key_type == GNUTLS_PK_GOST_01 ||
|
|
Packit |
aea12f |
key_type == GNUTLS_PK_GOST_12_256 ||
|
|
Packit |
aea12f |
key_type == GNUTLS_PK_GOST_12_512) {
|
|
Packit |
aea12f |
gnutls_datum_t y, x, k;
|
|
Packit |
aea12f |
gnutls_ecc_curve_t curve;
|
|
Packit |
aea12f |
gnutls_digest_algorithm_t digest;
|
|
Packit |
aea12f |
gnutls_gost_paramset_t paramset;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_export_gost_raw(key, &curve,
|
|
Packit |
aea12f |
&digest,
|
|
Packit |
aea12f |
¶mset,
|
|
Packit |
aea12f |
&x, &y, &k);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error in key GOST data export: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
else {
|
|
Packit |
aea12f |
print_gost_pkey(outfile, curve, digest, paramset,
|
|
Packit |
aea12f |
&k, &x, &y,
|
|
Packit |
aea12f |
cinfo->cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(x.data);
|
|
Packit |
aea12f |
gnutls_free(y.data);
|
|
Packit |
aea12f |
gnutls_free(k.data);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = lbuffer_size;
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_get_seed(key, &dig, lbuffer, &size);
|
|
Packit |
aea12f |
if (ret >= 0) {
|
|
Packit |
aea12f |
fprintf(outfile, "Validation parameters:\n");
|
|
Packit |
aea12f |
fprintf(outfile, "\tHash: %s\n",
|
|
Packit |
aea12f |
gnutls_digest_get_name(dig));
|
|
Packit |
aea12f |
fprintf(outfile, "\tSeed: %s\n",
|
|
Packit |
aea12f |
raw_to_hex(lbuffer, size));
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(outfile, "\n");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = lbuffer_size;
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_get_key_id(key, GNUTLS_KEYID_USE_SHA256, lbuffer, &size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error in key id calculation: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fprintf(outfile, "Public Key PIN:\n\tpin-sha256:%s\n",
|
|
Packit |
aea12f |
raw_to_base64(lbuffer, size));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fprintf(outfile, "Public Key ID:\n\tsha256:%s\n",
|
|
Packit |
aea12f |
raw_to_hex(lbuffer, size));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = lbuffer_size;
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_get_key_id(key, GNUTLS_KEYID_USE_SHA1, lbuffer, &size);
|
|
Packit |
aea12f |
if (ret >= 0) {
|
|
Packit |
aea12f |
fprintf(outfile, "\tsha1:%s\n",
|
|
Packit |
aea12f |
raw_to_hex(lbuffer, size));
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
fprintf(outfile, "\n");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void
|
|
Packit |
aea12f |
print_private_key(FILE *outfile, common_info_st * cinfo, gnutls_x509_privkey_t key)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!key)
|
|
Packit |
aea12f |
return;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Only print private key parameters when an unencrypted
|
|
Packit |
aea12f |
* format is used */
|
|
Packit |
aea12f |
switch_to_pkcs8_when_needed(cinfo, key, gnutls_x509_privkey_get_pk_algorithm(key));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!cinfo->pkcs8) {
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
if (cinfo->outtext)
|
|
Packit Service |
991b93 |
privkey_info_int(outfile, cinfo, key);
|
|
Packit Service |
991b93 |
|
|
Packit |
aea12f |
size = lbuffer_size;
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_export(key, cinfo->outcert_format,
|
|
Packit |
aea12f |
lbuffer, &size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "privkey_export: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
unsigned int flags = 0;
|
|
Packit |
aea12f |
const char *pass;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
pass = get_password(cinfo, &flags, 0);
|
|
Packit |
aea12f |
flags |= cipher_to_flags(cinfo->pkcs_cipher);
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
if (cinfo->outtext && (flags & GNUTLS_PKCS_PLAIN))
|
|
Packit Service |
991b93 |
privkey_info_int(outfile, cinfo, key);
|
|
Packit Service |
991b93 |
|
|
Packit |
aea12f |
size = lbuffer_size;
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_privkey_export_pkcs8(key, cinfo->outcert_format,
|
|
Packit |
aea12f |
pass, flags, lbuffer,
|
|
Packit |
aea12f |
&size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "privkey_export_pkcs8: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fwrite(lbuffer, 1, size, outfile);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* If how is zero then the included parameters are used.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int generate_prime(FILE * outfile, int how, common_info_st * info)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_dh_params_t dh_params;
|
|
Packit |
aea12f |
gnutls_datum_t p, g;
|
|
Packit |
aea12f |
int bits = get_bits(GNUTLS_PK_DH, info->bits, info->sec_param, 1);
|
|
Packit |
aea12f |
unsigned int q_bits = 0, key_bits = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fix_lbuffer(0);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_dh_params_init(&dh_params);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (how != 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Generating DH parameters (%d bits)...\n",
|
|
Packit |
aea12f |
bits);
|
|
Packit |
aea12f |
fprintf(stderr, "(might take long time)\n");
|
|
Packit |
aea12f |
} else
|
|
Packit |
aea12f |
fprintf(stderr, "Retrieving DH parameters...\n");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (how != 0) {
|
|
Packit |
aea12f |
if (info->provable != 0) {
|
|
Packit |
aea12f |
gnutls_x509_privkey_t pkey;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_init(&pkey);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error initializing key: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->seed_size > 0) {
|
|
Packit |
aea12f |
gnutls_keygen_data_st data;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->seed_size < 32) {
|
|
Packit |
aea12f |
fprintf(stderr, "For DH parameter generation a 32-byte seed value or larger is expected (have: %d); use -d 2 for more information.\n", (int)info->seed_size);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
data.type = GNUTLS_KEYGEN_SEED;
|
|
Packit |
aea12f |
data.data = (void*)info->seed;
|
|
Packit |
aea12f |
data.size = info->seed_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_generate2(pkey, GNUTLS_PK_DSA, bits, GNUTLS_PRIVKEY_FLAG_PROVABLE, &data, 1);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
ret = gnutls_x509_privkey_generate(pkey, GNUTLS_PK_DSA, bits, GNUTLS_PRIVKEY_FLAG_PROVABLE);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error generating DSA parameters: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->outcert_format == GNUTLS_X509_FMT_PEM) {
|
|
Packit |
aea12f |
print_private_key(outfile, info, pkey);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_dh_params_import_dsa(dh_params, pkey);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error importing DSA parameters: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_x509_privkey_deinit(pkey);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
ret = gnutls_dh_params_generate2(dh_params, bits);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Error generating parameters: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_dh_params_export_raw(dh_params, &p, &g,
|
|
Packit |
aea12f |
&q_bits);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error exporting parameters: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
if (info->provable != 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "The DH parameters obtained via this option are not provable\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
#if defined(ENABLE_DHE) || defined(ENABLE_ANON)
|
|
Packit |
aea12f |
if (bits <= 2048) {
|
|
Packit |
aea12f |
p = gnutls_ffdhe_2048_group_prime;
|
|
Packit |
aea12f |
g = gnutls_ffdhe_2048_group_generator;
|
|
Packit |
aea12f |
key_bits = gnutls_ffdhe_2048_key_bits;
|
|
Packit |
aea12f |
} else if (bits <= 3072) {
|
|
Packit |
aea12f |
p = gnutls_ffdhe_3072_group_prime;
|
|
Packit |
aea12f |
g = gnutls_ffdhe_3072_group_generator;
|
|
Packit |
aea12f |
key_bits = gnutls_ffdhe_3072_key_bits;
|
|
Packit |
aea12f |
} else if (bits <= 4096) {
|
|
Packit |
aea12f |
p = gnutls_ffdhe_4096_group_prime;
|
|
Packit |
aea12f |
g = gnutls_ffdhe_4096_group_generator;
|
|
Packit |
aea12f |
key_bits = gnutls_ffdhe_4096_key_bits;
|
|
Packit |
aea12f |
} else if (bits <= 6144) {
|
|
Packit |
aea12f |
p = gnutls_ffdhe_6144_group_prime;
|
|
Packit |
aea12f |
g = gnutls_ffdhe_6144_group_generator;
|
|
Packit |
aea12f |
key_bits = gnutls_ffdhe_6144_key_bits;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
p = gnutls_ffdhe_8192_group_prime;
|
|
Packit |
aea12f |
g = gnutls_ffdhe_8192_group_generator;
|
|
Packit |
aea12f |
key_bits = gnutls_ffdhe_8192_key_bits;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_dh_params_import_raw2(dh_params, &p, &g, key_bits);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error exporting parameters: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
#elif defined(ENABLE_SRP)
|
|
Packit |
aea12f |
if (bits <= 1024) {
|
|
Packit |
aea12f |
p = gnutls_srp_1024_group_prime;
|
|
Packit |
aea12f |
g = gnutls_srp_1024_group_generator;
|
|
Packit |
aea12f |
} else if (bits <= 1536) {
|
|
Packit |
aea12f |
p = gnutls_srp_1536_group_prime;
|
|
Packit |
aea12f |
g = gnutls_srp_1536_group_generator;
|
|
Packit |
aea12f |
} else if (bits <= 2048) {
|
|
Packit |
aea12f |
p = gnutls_srp_2048_group_prime;
|
|
Packit |
aea12f |
g = gnutls_srp_2048_group_generator;
|
|
Packit |
aea12f |
} else if (bits <= 3072) {
|
|
Packit |
aea12f |
p = gnutls_srp_3072_group_prime;
|
|
Packit |
aea12f |
g = gnutls_srp_3072_group_generator;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
p = gnutls_srp_4096_group_prime;
|
|
Packit |
aea12f |
g = gnutls_srp_4096_group_generator;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_dh_params_import_raw(dh_params, &p, &g);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Error exporting parameters: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
#else
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Parameters unavailable as SRP is disabled.\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
#endif
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (info->outtext)
|
|
Packit |
aea12f |
print_dh_info(outfile, &p, &g, q_bits, info->cprint);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!info->cprint) { /* generate a PKCS#3 structure */
|
|
Packit |
aea12f |
size_t len = lbuffer_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_dh_params_export_pkcs3(dh_params,
|
|
Packit |
aea12f |
info->outcert_format,
|
|
Packit |
aea12f |
lbuffer, &len;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret == 0) {
|
|
Packit |
aea12f |
if (info->outcert_format == GNUTLS_X509_FMT_PEM)
|
|
Packit |
aea12f |
fprintf(outfile, "\n%s", lbuffer);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
fwrite(lbuffer, 1, len, outfile);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fprintf(stderr, "Error: %s\n",
|
|
Packit |
aea12f |
gnutls_strerror(ret));
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (how != 0) {
|
|
Packit |
aea12f |
gnutls_free(p.data);
|
|
Packit |
aea12f |
gnutls_free(g.data);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_dh_params_deinit(dh_params);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void decode_seed(gnutls_datum_t *seed, const char *hex, unsigned hex_size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
size_t seed_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
seed->size = hex_size;
|
|
Packit |
aea12f |
seed->data = malloc(hex_size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (seed->data == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "memory error\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
seed_size = hex_size;
|
|
Packit |
aea12f |
ret = gnutls_hex2bin(hex, hex_size, seed->data, &seed_size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
fprintf(stderr, "Could not hex decode data: %s\n", gnutls_strerror(ret));
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
seed->size = seed_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_pk_algorithm_t figure_key_type(const char *key_type)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (strcasecmp(key_type, "rsa") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_RSA;
|
|
Packit |
aea12f |
else if (strcasecmp(key_type, "rsa-pss") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_RSA_PSS;
|
|
Packit |
aea12f |
else if (strcasecmp(key_type, "ed25519") == 0 || strcasecmp(key_type, "eddsa") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_EDDSA_ED25519;
|
|
Packit Service |
991b93 |
else if (strcasecmp(key_type, "ed448") == 0)
|
|
Packit Service |
991b93 |
return GNUTLS_PK_EDDSA_ED448;
|
|
Packit |
aea12f |
else if (strcasecmp(key_type, "dsa") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_DSA;
|
|
Packit |
aea12f |
else if (strcasecmp(key_type, "ecdsa") == 0 || strcasecmp(key_type, "ecc") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_ECDSA;
|
|
Packit |
aea12f |
else if (strcasecmp(key_type, "gost01") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_GOST_01;
|
|
Packit |
aea12f |
else if (strcasecmp(key_type, "gost12-256") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_GOST_12_256;
|
|
Packit |
aea12f |
else if (strcasecmp(key_type, "gost12-512") == 0)
|
|
Packit |
aea12f |
return GNUTLS_PK_GOST_12_512;
|
|
Packit |
aea12f |
else {
|
|
Packit |
aea12f |
fprintf(stderr, "unknown key type: %s\n", key_type);
|
|
Packit |
aea12f |
return GNUTLS_PK_UNKNOWN;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_digest_algorithm_t hash_to_id(const char *hash)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (strcasecmp(hash, "md5") == 0) {
|
|
Packit |
aea12f |
fprintf(stderr,
|
|
Packit |
aea12f |
"Warning: MD5 is broken, and should not be used any more for digital signatures.\n");
|
|
Packit |
aea12f |
return GNUTLS_DIG_MD5;
|
|
Packit |
aea12f |
} else if (strcasecmp(hash, "sha1") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA1;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha256") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA256;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha224") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA224;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha384") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA384;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha512") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA512;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha3-256") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA3_256;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha3-224") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA3_224;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha3-384") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA3_384;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "sha3-512") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_SHA3_512;
|
|
Packit |
aea12f |
else if (strcasecmp(hash, "rmd160") == 0)
|
|
Packit |
aea12f |
return GNUTLS_DIG_RMD160;
|
|
Packit |
aea12f |
else {
|
|
Packit |
aea12f |
return gnutls_digest_get_id(hash);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void sign_params_to_flags(common_info_st *cinfo, const char *params)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char *p, *sp;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
sp = strdup(params);
|
|
Packit |
aea12f |
if (sp == NULL) {
|
|
Packit |
aea12f |
fprintf(stderr, "memory error\n");
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
p = strtok(sp, ",");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
while(p != NULL) {
|
|
Packit |
aea12f |
if (strcasecmp(p, "rsa-pss")==0) {
|
|
Packit |
aea12f |
cinfo->rsa_pss_sign = 1;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
fprintf(stderr, "Unknown signature parameter: %s\n", p);
|
|
Packit |
aea12f |
app_exit(1);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
p=strtok(NULL, ",");
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
free(sp);
|
|
Packit |
aea12f |
}
|