mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-25 01:01:40 -04:00
moved files to comply with rest of directory structure of RS
git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-OpenPGP@5260 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
3b5816e4f8
commit
ba0cca637b
72 changed files with 78 additions and 103 deletions
812
openpgpsdk/src/openpgpsdk/openssl_crypto.c
Normal file
812
openpgpsdk/src/openpgpsdk/openssl_crypto.c
Normal file
|
@ -0,0 +1,812 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
|
||||
* All rights reserved.
|
||||
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
|
||||
* their moral rights under the UK Copyright Design and Patents Act 1988 to
|
||||
* be recorded as the authors of this copyright work.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openpgpsdk/configure.h>
|
||||
#include <openpgpsdk/crypto.h>
|
||||
#include <openpgpsdk/keyring.h>
|
||||
#include <openpgpsdk/readerwriter.h>
|
||||
#include "keyring_local.h"
|
||||
#include <openpgpsdk/std_print.h>
|
||||
|
||||
#include <openpgpsdk/final.h>
|
||||
|
||||
static int debug=0;
|
||||
|
||||
void test_secret_key(const ops_secret_key_t *skey)
|
||||
{
|
||||
RSA* test=RSA_new();
|
||||
|
||||
test->n=BN_dup(skey->public_key.key.rsa.n);
|
||||
test->e=BN_dup(skey->public_key.key.rsa.e);
|
||||
|
||||
test->d=BN_dup(skey->key.rsa.d);
|
||||
test->p=BN_dup(skey->key.rsa.p);
|
||||
test->q=BN_dup(skey->key.rsa.q);
|
||||
|
||||
assert(RSA_check_key(test)==1);
|
||||
RSA_free(test);
|
||||
}
|
||||
|
||||
static void md5_init(ops_hash_t *hash)
|
||||
{
|
||||
assert(!hash->data);
|
||||
hash->data=malloc(sizeof(MD5_CTX));
|
||||
MD5_Init(hash->data);
|
||||
}
|
||||
|
||||
static void md5_add(ops_hash_t *hash,const unsigned char *data,unsigned length)
|
||||
{
|
||||
MD5_Update(hash->data,data,length);
|
||||
}
|
||||
|
||||
static unsigned md5_finish(ops_hash_t *hash,unsigned char *out)
|
||||
{
|
||||
MD5_Final(out,hash->data);
|
||||
free(hash->data);
|
||||
hash->data=NULL;
|
||||
return 16;
|
||||
}
|
||||
|
||||
static ops_hash_t md5={OPS_HASH_MD5,MD5_DIGEST_LENGTH,"MD5",md5_init,md5_add,
|
||||
md5_finish,NULL};
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief Initialise to MD5
|
||||
\param hash Hash to initialise
|
||||
*/
|
||||
void ops_hash_md5(ops_hash_t *hash)
|
||||
{
|
||||
*hash=md5;
|
||||
}
|
||||
|
||||
static void sha1_init(ops_hash_t *hash)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr,"***\n***\nsha1_init\n***\n");
|
||||
}
|
||||
assert(!hash->data);
|
||||
hash->data=malloc(sizeof(SHA_CTX));
|
||||
SHA1_Init(hash->data);
|
||||
}
|
||||
|
||||
static void sha1_add(ops_hash_t *hash,const unsigned char *data,
|
||||
unsigned length)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
unsigned int i=0;
|
||||
fprintf(stderr,"adding %d to hash:\n ", length);
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
fprintf(stderr,"0x%02x ", data[i]);
|
||||
if (!((i+1) % 16))
|
||||
fprintf(stderr,"\n");
|
||||
else if (!((i+1) % 8))
|
||||
fprintf(stderr," ");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
SHA1_Update(hash->data,data,length);
|
||||
}
|
||||
|
||||
static unsigned sha1_finish(ops_hash_t *hash,unsigned char *out)
|
||||
{
|
||||
SHA1_Final(out,hash->data);
|
||||
if (debug)
|
||||
{
|
||||
unsigned i=0;
|
||||
fprintf(stderr,"***\n***\nsha1_finish\n***\n");
|
||||
for (i=0; i<SHA_DIGEST_LENGTH; i++)
|
||||
fprintf(stderr,"0x%02x ",out[i]);
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
free(hash->data);
|
||||
hash->data=NULL;
|
||||
return SHA_DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
static ops_hash_t sha1={OPS_HASH_SHA1,SHA_DIGEST_LENGTH,"SHA1",sha1_init,
|
||||
sha1_add,sha1_finish,NULL};
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief Initialise to SHA1
|
||||
\param hash Hash to initialise
|
||||
*/
|
||||
void ops_hash_sha1(ops_hash_t *hash)
|
||||
{
|
||||
*hash=sha1;
|
||||
}
|
||||
|
||||
static void sha256_init(ops_hash_t *hash)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr,"***\n***\nsha256_init\n***\n");
|
||||
}
|
||||
assert(!hash->data);
|
||||
hash->data=malloc(sizeof(SHA256_CTX));
|
||||
SHA256_Init(hash->data);
|
||||
}
|
||||
|
||||
static void sha256_add(ops_hash_t *hash,const unsigned char *data,
|
||||
unsigned length)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
unsigned int i=0;
|
||||
fprintf(stderr,"adding %d to hash:\n ", length);
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
fprintf(stderr,"0x%02x ", data[i]);
|
||||
if (!((i+1) % 16))
|
||||
fprintf(stderr,"\n");
|
||||
else if (!((i+1) % 8))
|
||||
fprintf(stderr," ");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
SHA256_Update(hash->data,data,length);
|
||||
}
|
||||
|
||||
static unsigned sha256_finish(ops_hash_t *hash,unsigned char *out)
|
||||
{
|
||||
SHA256_Final(out,hash->data);
|
||||
if (debug)
|
||||
{
|
||||
unsigned i=0;
|
||||
fprintf(stderr,"***\n***\nsha1_finish\n***\n");
|
||||
for (i=0; i<SHA256_DIGEST_LENGTH; i++)
|
||||
fprintf(stderr,"0x%02x ",out[i]);
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
free(hash->data);
|
||||
hash->data=NULL;
|
||||
return SHA256_DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
static ops_hash_t sha256={OPS_HASH_SHA256,SHA256_DIGEST_LENGTH,"SHA256",sha256_init,
|
||||
sha256_add,sha256_finish,NULL};
|
||||
|
||||
void ops_hash_sha256(ops_hash_t *hash)
|
||||
{
|
||||
*hash=sha256;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA384
|
||||
*/
|
||||
|
||||
static void sha384_init(ops_hash_t *hash)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr,"***\n***\nsha384_init\n***\n");
|
||||
}
|
||||
assert(!hash->data);
|
||||
hash->data=malloc(sizeof(SHA512_CTX));
|
||||
SHA384_Init(hash->data);
|
||||
}
|
||||
|
||||
static void sha384_add(ops_hash_t *hash,const unsigned char *data,
|
||||
unsigned length)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
unsigned int i=0;
|
||||
fprintf(stderr,"adding %d to hash:\n ", length);
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
fprintf(stderr,"0x%02x ", data[i]);
|
||||
if (!((i+1) % 16))
|
||||
fprintf(stderr,"\n");
|
||||
else if (!((i+1) % 8))
|
||||
fprintf(stderr," ");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
SHA384_Update(hash->data,data,length);
|
||||
}
|
||||
|
||||
static unsigned sha384_finish(ops_hash_t *hash,unsigned char *out)
|
||||
{
|
||||
SHA384_Final(out,hash->data);
|
||||
if (debug)
|
||||
{
|
||||
unsigned i=0;
|
||||
fprintf(stderr,"***\n***\nsha1_finish\n***\n");
|
||||
for (i=0; i<SHA384_DIGEST_LENGTH; i++)
|
||||
fprintf(stderr,"0x%02x ",out[i]);
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
free(hash->data);
|
||||
hash->data=NULL;
|
||||
return SHA384_DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
static ops_hash_t sha384={OPS_HASH_SHA384,SHA384_DIGEST_LENGTH,"SHA384",sha384_init,
|
||||
sha384_add,sha384_finish,NULL};
|
||||
|
||||
void ops_hash_sha384(ops_hash_t *hash)
|
||||
{
|
||||
*hash=sha384;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA512
|
||||
*/
|
||||
|
||||
static void sha512_init(ops_hash_t *hash)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr,"***\n***\nsha512_init\n***\n");
|
||||
}
|
||||
assert(!hash->data);
|
||||
hash->data=malloc(sizeof(SHA512_CTX));
|
||||
SHA512_Init(hash->data);
|
||||
}
|
||||
|
||||
static void sha512_add(ops_hash_t *hash,const unsigned char *data,
|
||||
unsigned length)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
unsigned int i=0;
|
||||
fprintf(stderr,"adding %d to hash:\n ", length);
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
fprintf(stderr,"0x%02x ", data[i]);
|
||||
if (!((i+1) % 16))
|
||||
fprintf(stderr,"\n");
|
||||
else if (!((i+1) % 8))
|
||||
fprintf(stderr," ");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
SHA512_Update(hash->data,data,length);
|
||||
}
|
||||
|
||||
static unsigned sha512_finish(ops_hash_t *hash,unsigned char *out)
|
||||
{
|
||||
SHA512_Final(out,hash->data);
|
||||
if (debug)
|
||||
{
|
||||
unsigned i=0;
|
||||
fprintf(stderr,"***\n***\nsha1_finish\n***\n");
|
||||
for (i=0; i<SHA512_DIGEST_LENGTH; i++)
|
||||
fprintf(stderr,"0x%02x ",out[i]);
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
free(hash->data);
|
||||
hash->data=NULL;
|
||||
return SHA512_DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
static ops_hash_t sha512={OPS_HASH_SHA512,SHA512_DIGEST_LENGTH,"SHA512",sha512_init,
|
||||
sha512_add,sha512_finish,NULL};
|
||||
|
||||
void ops_hash_sha512(ops_hash_t *hash)
|
||||
{
|
||||
*hash=sha512;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224
|
||||
*/
|
||||
|
||||
static void sha224_init(ops_hash_t *hash)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr,"***\n***\nsha1_init\n***\n");
|
||||
}
|
||||
assert(!hash->data);
|
||||
hash->data=malloc(sizeof(SHA256_CTX));
|
||||
SHA224_Init(hash->data);
|
||||
}
|
||||
|
||||
static void sha224_add(ops_hash_t *hash,const unsigned char *data,
|
||||
unsigned length)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
unsigned int i=0;
|
||||
fprintf(stderr,"adding %d to hash:\n ", length);
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
fprintf(stderr,"0x%02x ", data[i]);
|
||||
if (!((i+1) % 16))
|
||||
fprintf(stderr,"\n");
|
||||
else if (!((i+1) % 8))
|
||||
fprintf(stderr," ");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
SHA224_Update(hash->data,data,length);
|
||||
}
|
||||
|
||||
static unsigned sha224_finish(ops_hash_t *hash,unsigned char *out)
|
||||
{
|
||||
SHA224_Final(out,hash->data);
|
||||
if (debug)
|
||||
{
|
||||
unsigned i=0;
|
||||
fprintf(stderr,"***\n***\nsha1_finish\n***\n");
|
||||
for (i=0; i<SHA224_DIGEST_LENGTH; i++)
|
||||
fprintf(stderr,"0x%02x ",out[i]);
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
free(hash->data);
|
||||
hash->data=NULL;
|
||||
return SHA224_DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
static ops_hash_t sha224={OPS_HASH_SHA224,SHA224_DIGEST_LENGTH,"SHA224",sha224_init,
|
||||
sha224_add,sha224_finish,NULL};
|
||||
|
||||
void ops_hash_sha224(ops_hash_t *hash)
|
||||
{
|
||||
*hash=sha224;
|
||||
}
|
||||
|
||||
ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length,
|
||||
const ops_dsa_signature_t *sig,
|
||||
const ops_dsa_public_key_t *dsa)
|
||||
{
|
||||
DSA_SIG *osig;
|
||||
DSA *odsa;
|
||||
int ret;
|
||||
|
||||
osig=DSA_SIG_new();
|
||||
osig->r=sig->r;
|
||||
osig->s=sig->s;
|
||||
|
||||
if(BN_num_bits(dsa->q) != 160)
|
||||
{
|
||||
fprintf(stderr,"(WW) ops_dsa_verify: openssl does only supports 'q' of 160 bits. Current is %d bits.\n",BN_num_bits(dsa->q)) ;
|
||||
return ops_false ;
|
||||
}
|
||||
|
||||
odsa=DSA_new();
|
||||
odsa->p=dsa->p;
|
||||
odsa->q=dsa->q;
|
||||
odsa->g=dsa->g;
|
||||
odsa->pub_key=dsa->y;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr,"hash passed in:\n");
|
||||
unsigned i;
|
||||
for (i=0; i<hash_length; i++)
|
||||
{
|
||||
fprintf(stderr,"%02x ", hash[i]);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
//printf("hash_length=%ld\n", hash_length);
|
||||
//printf("Q=%d\n", BN_num_bytes(odsa->q));
|
||||
unsigned int qlen=BN_num_bytes(odsa->q);
|
||||
if (qlen < hash_length)
|
||||
hash_length=qlen;
|
||||
// ret=DSA_do_verify(hash,hash_length,osig,odsa);
|
||||
ret=DSA_do_verify(hash,hash_length,osig,odsa);
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr,"ret=%d\n",ret);
|
||||
}
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
ERR_load_crypto_strings() ;
|
||||
unsigned long err = 0 ;
|
||||
while(err = ERR_get_error())
|
||||
fprintf(stderr,"DSA_do_verify(): ERR = %ld. lib error:\"%s\", func_error:\"%s\", reason:\"%s\"\n",err,ERR_lib_error_string(err),ERR_func_error_string(err),ERR_reason_error_string(err)) ;
|
||||
//assert(ret >= 0);
|
||||
return ops_false ;
|
||||
}
|
||||
|
||||
odsa->p=odsa->q=odsa->g=odsa->pub_key=NULL;
|
||||
DSA_free(odsa);
|
||||
|
||||
osig->r=osig->s=NULL;
|
||||
DSA_SIG_free(osig);
|
||||
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief Recovers message digest from the signature
|
||||
\param out Where to write decrypted data to
|
||||
\param in Encrypted data
|
||||
\param length Length of encrypted data
|
||||
\param rsa RSA public key
|
||||
\return size of recovered message digest
|
||||
*/
|
||||
int ops_rsa_public_decrypt(unsigned char *out,const unsigned char *in,
|
||||
size_t length,const ops_rsa_public_key_t *rsa)
|
||||
{
|
||||
RSA *orsa;
|
||||
int n;
|
||||
|
||||
orsa=RSA_new();
|
||||
orsa->n=rsa->n;
|
||||
orsa->e=rsa->e;
|
||||
|
||||
n=RSA_public_decrypt(length,in,out,orsa,RSA_NO_PADDING);
|
||||
|
||||
orsa->n=orsa->e=NULL;
|
||||
RSA_free(orsa);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief Signs data with RSA
|
||||
\param out Where to write signature
|
||||
\param in Data to sign
|
||||
\param length Length of data
|
||||
\param srsa RSA secret key
|
||||
\param rsa RSA public key
|
||||
\return number of bytes decrypted
|
||||
*/
|
||||
int ops_rsa_private_encrypt(unsigned char *out,const unsigned char *in,
|
||||
size_t length,const ops_rsa_secret_key_t *srsa,
|
||||
const ops_rsa_public_key_t *rsa)
|
||||
{
|
||||
RSA *orsa;
|
||||
int n;
|
||||
|
||||
orsa=RSA_new();
|
||||
orsa->n=rsa->n; // XXX: do we need n?
|
||||
orsa->d=srsa->d;
|
||||
orsa->p=srsa->q;
|
||||
orsa->q=srsa->p;
|
||||
|
||||
/* debug */
|
||||
orsa->e=rsa->e;
|
||||
// If this isn't set, it's very likely that the programmer hasn't
|
||||
// decrypted the secret key. RSA_check_key segfaults in that case.
|
||||
// Use ops_decrypt_secret_key_from_data() to do that.
|
||||
assert(orsa->d);
|
||||
assert(RSA_check_key(orsa) == 1);
|
||||
orsa->e=NULL;
|
||||
/* end debug */
|
||||
|
||||
n=RSA_private_encrypt(length,in,out,orsa,RSA_NO_PADDING);
|
||||
|
||||
orsa->n=orsa->d=orsa->p=orsa->q=NULL;
|
||||
RSA_free(orsa);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief Decrypts RSA-encrypted data
|
||||
\param out Where to write the plaintext
|
||||
\param in Encrypted data
|
||||
\param length Length of encrypted data
|
||||
\param srsa RSA secret key
|
||||
\param rsa RSA public key
|
||||
\return size of recovered plaintext
|
||||
*/
|
||||
int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in,
|
||||
size_t length,const ops_rsa_secret_key_t *srsa,
|
||||
const ops_rsa_public_key_t *rsa)
|
||||
{
|
||||
RSA *orsa;
|
||||
int n;
|
||||
char errbuf[1024];
|
||||
|
||||
orsa=RSA_new();
|
||||
orsa->n=rsa->n; // XXX: do we need n?
|
||||
orsa->d=srsa->d;
|
||||
orsa->p=srsa->q;
|
||||
orsa->q=srsa->p;
|
||||
|
||||
/* debug */
|
||||
orsa->e=rsa->e;
|
||||
assert(RSA_check_key(orsa) == 1);
|
||||
orsa->e=NULL;
|
||||
/* end debug */
|
||||
|
||||
n=RSA_private_decrypt(length,in,out,orsa,RSA_NO_PADDING);
|
||||
|
||||
// printf("ops_rsa_private_decrypt: n=%d\n",n);
|
||||
|
||||
errbuf[0]='\0';
|
||||
if (n==-1)
|
||||
{
|
||||
unsigned long err=ERR_get_error();
|
||||
ERR_error_string(err,&errbuf[0]);
|
||||
fprintf(stderr,"openssl error : %s\n",errbuf);
|
||||
}
|
||||
orsa->n=orsa->d=orsa->p=orsa->q=NULL;
|
||||
RSA_free(orsa);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief RSA-encrypts data
|
||||
\param out Where to write the encrypted data
|
||||
\param in Plaintext
|
||||
\param length Size of plaintext
|
||||
\param rsa RSA Public Key
|
||||
*/
|
||||
int ops_rsa_public_encrypt(unsigned char *out,const unsigned char *in,
|
||||
size_t length,const ops_rsa_public_key_t *rsa)
|
||||
{
|
||||
RSA *orsa;
|
||||
int n;
|
||||
|
||||
// printf("ops_rsa_public_encrypt: length=%ld\n", length);
|
||||
|
||||
orsa=RSA_new();
|
||||
orsa->n=rsa->n;
|
||||
orsa->e=rsa->e;
|
||||
|
||||
// printf("len: %ld\n", length);
|
||||
// ops_print_bn("n: ", orsa->n);
|
||||
// ops_print_bn("e: ", orsa->e);
|
||||
n=RSA_public_encrypt(length,in,out,orsa,RSA_NO_PADDING);
|
||||
|
||||
if (n==-1)
|
||||
{
|
||||
BIO *fd_out;
|
||||
fd_out=BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
|
||||
ERR_print_errors(fd_out);
|
||||
}
|
||||
|
||||
orsa->n=orsa->e=NULL;
|
||||
RSA_free(orsa);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief initialises openssl
|
||||
\note Would usually call ops_init() instead
|
||||
\sa ops_init()
|
||||
*/
|
||||
void ops_crypto_init()
|
||||
{
|
||||
#ifdef DMALLOC
|
||||
CRYPTO_malloc_debug_init();
|
||||
CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
|
||||
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Crypto
|
||||
\brief Finalise openssl
|
||||
\note Would usually call ops_finish() instead
|
||||
\sa ops_finish()
|
||||
*/
|
||||
void ops_crypto_finish()
|
||||
{
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
// FIXME: what should we do instead (function is deprecated)?
|
||||
// ERR_remove_state(0);
|
||||
#ifdef DMALLOC
|
||||
CRYPTO_mem_leaks_fp(stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup Core_Hashes
|
||||
\brief Get Hash name
|
||||
\param hash Hash struct
|
||||
\return Hash name
|
||||
*/
|
||||
const char *ops_text_from_hash(ops_hash_t *hash)
|
||||
{ return hash->name; }
|
||||
|
||||
/**
|
||||
\ingroup HighLevel_KeyGenerate
|
||||
\brief Generates an RSA keypair
|
||||
\param numbits Modulus size
|
||||
\param e Public Exponent
|
||||
\param keydata Pointer to keydata struct to hold new key
|
||||
\return ops_true if key generated successfully; otherwise ops_false
|
||||
\note It is the caller's responsibility to call ops_keydata_free(keydata)
|
||||
*/
|
||||
ops_boolean_t ops_rsa_generate_keypair(const int numbits, const unsigned long e,
|
||||
ops_keydata_t* keydata)
|
||||
{
|
||||
ops_secret_key_t *skey=NULL;
|
||||
RSA *rsa=RSA_new();
|
||||
BN_CTX *ctx=BN_CTX_new();
|
||||
BIGNUM *ebn=BN_new();
|
||||
|
||||
ops_keydata_init(keydata,OPS_PTAG_CT_SECRET_KEY);
|
||||
skey=ops_get_writable_secret_key_from_data(keydata);
|
||||
|
||||
// generate the key pair
|
||||
|
||||
BN_set_word(ebn,e);
|
||||
RSA_generate_key_ex(rsa,numbits,ebn,NULL);
|
||||
|
||||
// populate ops key from ssl key
|
||||
|
||||
skey->public_key.version=4;
|
||||
skey->public_key.creation_time=time(NULL);
|
||||
skey->public_key.days_valid=0;
|
||||
skey->public_key.algorithm= OPS_PKA_RSA;
|
||||
|
||||
skey->public_key.key.rsa.n=BN_dup(rsa->n);
|
||||
skey->public_key.key.rsa.e=BN_dup(rsa->e);
|
||||
|
||||
skey->s2k_usage=OPS_S2KU_ENCRYPTED_AND_HASHED;
|
||||
skey->s2k_specifier=OPS_S2KS_SALTED;
|
||||
//skey->s2k_specifier=OPS_S2KS_SIMPLE;
|
||||
skey->algorithm=OPS_SA_CAST5; // \todo make param
|
||||
skey->hash_algorithm=OPS_HASH_SHA1; // \todo make param
|
||||
skey->octet_count=0;
|
||||
skey->checksum=0;
|
||||
|
||||
skey->key.rsa.d=BN_dup(rsa->d);
|
||||
skey->key.rsa.p=BN_dup(rsa->p);
|
||||
skey->key.rsa.q=BN_dup(rsa->q);
|
||||
skey->key.rsa.u=BN_mod_inverse(NULL,rsa->p, rsa->q, ctx);
|
||||
assert(skey->key.rsa.u);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
RSA_free(rsa);
|
||||
|
||||
ops_keyid(keydata->key_id, &keydata->key.skey.public_key);
|
||||
ops_fingerprint(&keydata->fingerprint, &keydata->key.skey.public_key);
|
||||
|
||||
// Generate checksum
|
||||
|
||||
ops_create_info_t *cinfo=NULL;
|
||||
ops_memory_t *mem=NULL;
|
||||
|
||||
ops_setup_memory_write(&cinfo, &mem, 128);
|
||||
|
||||
ops_push_skey_checksum_writer(cinfo, skey);
|
||||
|
||||
switch(skey->public_key.algorithm)
|
||||
{
|
||||
// case OPS_PKA_DSA:
|
||||
// return ops_write_mpi(key->key.dsa.x,info);
|
||||
|
||||
case OPS_PKA_RSA:
|
||||
case OPS_PKA_RSA_ENCRYPT_ONLY:
|
||||
case OPS_PKA_RSA_SIGN_ONLY:
|
||||
if(!ops_write_mpi(skey->key.rsa.d,cinfo)
|
||||
|| !ops_write_mpi(skey->key.rsa.p,cinfo)
|
||||
|| !ops_write_mpi(skey->key.rsa.q,cinfo)
|
||||
|| !ops_write_mpi(skey->key.rsa.u,cinfo))
|
||||
return ops_false;
|
||||
break;
|
||||
|
||||
// case OPS_PKA_ELGAMAL:
|
||||
// return ops_write_mpi(key->key.elgamal.x,info);
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
// close rather than pop, since its the only one on the stack
|
||||
ops_writer_close(cinfo);
|
||||
ops_teardown_memory_write(cinfo, mem);
|
||||
|
||||
// should now have checksum in skey struct
|
||||
|
||||
// test
|
||||
if (debug)
|
||||
test_secret_key(skey);
|
||||
|
||||
return ops_true;
|
||||
}
|
||||
|
||||
/**
|
||||
\ingroup HighLevel_KeyGenerate
|
||||
\brief Creates a self-signed RSA keypair
|
||||
\param numbits Modulus size
|
||||
\param e Public Exponent
|
||||
\param userid User ID
|
||||
\return The new keypair or NULL
|
||||
|
||||
\note It is the caller's responsibility to call ops_keydata_free(keydata)
|
||||
\sa ops_rsa_generate_keypair()
|
||||
\sa ops_keydata_free()
|
||||
*/
|
||||
ops_keydata_t* ops_rsa_create_selfsigned_keypair(const int numbits, const unsigned long e, ops_user_id_t * userid)
|
||||
{
|
||||
ops_keydata_t *keydata=NULL;
|
||||
|
||||
keydata=ops_keydata_new();
|
||||
|
||||
if (ops_rsa_generate_keypair(numbits, e, keydata) != ops_true
|
||||
|| ops_add_selfsigned_userid_to_keydata(keydata, userid) != ops_true)
|
||||
{
|
||||
ops_keydata_free(keydata);
|
||||
free(keydata) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return keydata;
|
||||
}
|
||||
|
||||
/*
|
||||
int ops_dsa_size(const ops_dsa_public_key_t *dsa)
|
||||
{
|
||||
int size;
|
||||
DSA *odsa;
|
||||
odsa=DSA_new();
|
||||
odsa->p=dsa->p;
|
||||
odsa->q=dsa->q;
|
||||
odsa->g=dsa->g;
|
||||
odsa->pub_key=dsa->y;
|
||||
|
||||
DSAparams_print_fp(stderr, odsa);
|
||||
size=DSA_size(odsa);
|
||||
|
||||
odsa->p=odsa->q=odsa->g=odsa->pub_key=odsa->priv_key=NULL;
|
||||
DSA_free(odsa);
|
||||
|
||||
return size;
|
||||
}
|
||||
*/
|
||||
|
||||
DSA_SIG* ops_dsa_sign(unsigned char* hashbuf, unsigned hashsize, const ops_dsa_secret_key_t *sdsa, const ops_dsa_public_key_t *dsa)
|
||||
{
|
||||
DSA *odsa;
|
||||
DSA_SIG *dsasig;
|
||||
|
||||
odsa=DSA_new();
|
||||
odsa->p=dsa->p;
|
||||
odsa->q=dsa->q;
|
||||
odsa->g=dsa->g;
|
||||
odsa->pub_key=dsa->y;
|
||||
odsa->priv_key=sdsa->x;
|
||||
|
||||
dsasig=DSA_do_sign(hashbuf,hashsize,odsa);
|
||||
|
||||
odsa->p=odsa->q=odsa->g=odsa->pub_key=odsa->priv_key=NULL;
|
||||
DSA_free(odsa);
|
||||
|
||||
return dsasig;
|
||||
}
|
||||
|
||||
// eof
|
Loading…
Add table
Add a link
Reference in a new issue