added two additional non packward compatible changes for future version 0.7, and improvements of verifications of certificate signatures

This commit is contained in:
csoler 2017-11-19 18:21:56 +01:00
parent 7472f78223
commit b4fdd4e0d0
8 changed files with 274 additions and 69 deletions

View File

@ -1,14 +1,31 @@
V07_NON_BACKWARD_COMPATIBLE_CHANGE_001:
What: Computes the node id by performing a sha256 hash of the certificate's PGP signature, instead of simply picking up the last 20 bytes of it.
Why: There is no real risk in forging a certificate with the same ID as the authentication is performed over the PGP signature of the certificate
which hashes the full SSL certificate (i.e. the full serialized CERT_INFO structure). However the possibility to
create two certificates with the same IDs is a problem, as it can be used to cause disturbance in the software.
What: Computes the node id by performing a sha256 hash of the certificate's PGP signature, instead of simply picking up the last 20 bytes of it.
Why: There is no real risk in forging a certificate with the same ID as the authentication is performed over the PGP signature of the certificate
which hashes the full SSL certificate (i.e. the full serialized CERT_INFO structure). However the possibility to
create two certificates with the same IDs is a problem, as it can be used to cause disturbance in the software.
Backward compat: makes connexions impossible with non patched peers, probably because the SSL id that is computed is not the same on both side,
and in particular unpatched peers see a cerficate with ID different (because computed with the old method) than the ID that was
submitted when making friends.
Backward compat: makes connexions impossible with non patched peers, probably because the SSL id that is computed is not the same on both side,
and in particular unpatched peers see a cerficate with ID different (because computed with the old method) than the ID that was
submitted when making friends.
Note: the advantage of basing the ID on the signature rather than the public key is not very clear, given that the signature is based on a hash
of the public key (and the rest of the certificate info).
V07_NON_BACKWARD_COMPATIBLE_CHANGE_002:
What: Use RSA+SHA256 instead of RSA+SHA1 for PGP certificate signatures
Why: Sha1 is likely to be prone to primary collisions anytime soon, so it is urgent to turn to a more secure solution.
Backward compat: unpatched peers are able to verify signatures since openpgp-sdk already handle it.
V07_NON_BACKWARD_COMPATIBLE_CHANGE_003:
What: Do not hash PGP certificate twice when signing
Why: hasing twice is not per se a security issue, but it makes it harder to change the settings for hashing.
Backward compat: patched peers cannot connect to non patched peers.
Note: the advantage of basing the ID on the signature rather than the public key is not very clear, given that the signature is based on a hash
of the public key (and the rest of the certificate info).

View File

@ -1382,7 +1382,11 @@ ops_secret_key_t *secret_key = NULL ;
// then do the signature.
ops_boolean_t not_raw = !use_raw_signature ;
ops_memory_t *memres = ops_sign_buf(data,len,(ops_sig_type_t)0x00,secret_key,ops_false,ops_false,not_raw,not_raw) ;
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ;
#else
ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA1,secret_key,ops_false,ops_false,not_raw,not_raw) ;
#endif
if(!memres)
return false ;
@ -1695,16 +1699,16 @@ bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src)
bool PGPHandler::parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id)
{
uint64_t issuer ;
PGPSignatureInfo info ;
if(!PGPKeyManagement::parseSignature(sign,signlen,issuer))
if(!PGPKeyManagement::parseSignature(sign,signlen,info))
return false ;
unsigned char bytes[8] ;
for(int i=0;i<8;++i)
{
bytes[7-i] = issuer & 0xff ;
issuer >>= 8 ;
bytes[7-i] = info.issuer & 0xff ;
info.issuer >>= 8 ;
}
issuer_id = RsPgpId(bytes) ;

View File

@ -160,7 +160,7 @@ uint32_t PGPKeyManagement::compute24bitsCRC(unsigned char *octets, size_t len)
return crc & 0xFFFFFFL;
}
bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sign_len, uint64_t& issuer)
bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sign_len, PGPSignatureInfo& info)
{
unsigned char *data = (unsigned char *)signature ;
@ -189,10 +189,10 @@ bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sig
if(signature_type != 4)
return false ;
data += 1 ; // skip version number
data += 1 ; // skip signature type
data += 1 ; // skip public key algorithm
data += 1 ; // skip hash algorithm
info.signature_version = data[0] ; data += 1 ; // skip version number
info.signature_type = data[0] ; data += 1 ; // skip signature type
info.public_key_algorithm = data[0] ; data += 1 ; // skip public key algorithm
info.hash_algorithm = data[0] ; data += 1 ; // skip hash algorithm
uint32_t hashed_size = 256u*data[0] + data[1] ;
data += 2 ;
@ -214,7 +214,7 @@ bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sig
if(subpacket_type == PGPKeyParser::PGP_PACKET_TAG_ISSUER && subpacket_size == 9)
{
issuer_found = true ;
issuer = PGPKeyParser::read_KeyID(data) ;
info.issuer = PGPKeyParser::read_KeyID(data) ;
}
else
data += subpacket_size-1 ; // we remove the size of subpacket type

View File

@ -41,6 +41,46 @@
#include <stdint.h>
#include <string>
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN = 0 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_MD5 = 1 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA1 = 2 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA256 = 8 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA512 = 10 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN = 0 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_ES = 1 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_E = 2 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_S = 3 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_DSA = 17 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_UNKNOWN = 0 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_V3 = 3 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_V4 = 4 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN = 0xff ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_BINARY_DOCUMENT = 0x00 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_CANONICAL_TEXT = 0x01 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_STANDALONE_SIG = 0x02 ;
// All other consts for signature types not used, so not defines.
class PGPSignatureInfo
{
public:
PGPSignatureInfo() :
signature_version (PGP_PACKET_TAG_SIGNATURE_VERSION_UNKNOWN),
signature_type (PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN),
issuer (0),
public_key_algorithm(PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN),
hash_algorithm (PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN)
{}
uint8_t signature_version ;
uint8_t signature_type ;
uint64_t issuer ;
uint8_t public_key_algorithm ;
uint8_t hash_algorithm ;
};
// This class handles GPG keys. For now we only clean them from signatures, but
// in the future, we might cache them to avoid unnecessary calls to gpgme.
//
@ -66,7 +106,7 @@ class PGPKeyManagement
//
static uint32_t compute24bitsCRC(unsigned char *data,size_t len) ;
static bool parseSignature(const unsigned char *signature, size_t sign_len, uint64_t &issuer) ;
static bool parseSignature(const unsigned char *signature, size_t sign_len, PGPSignatureInfo& info) ;
};
// This class handles the parsing of PGP packet headers under various (old and new) formats.
@ -74,6 +114,8 @@ class PGPKeyManagement
class PGPKeyParser
{
public:
// These constants correspond to packet tags from RFC4880
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY = 6 ;
static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ;

View File

@ -40,6 +40,7 @@
#include "rsitems/rsconfigitems.h"
#include "util/rsdir.h"
#include "util/rsstring.h"
#include "pgp/pgpkeyutil.h"
#include "retroshare/rspeers.h" // for RsPeerDetails structure
#include "retroshare/rsids.h" // for RsPeerDetails structure
@ -54,13 +55,17 @@
/* SSL connection diagnostic */
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN = 0x00 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_OK = 0x01 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID = 0x02 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN = 0x03 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR = 0x04 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING = 0x06 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN = 0x00 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_OK = 0x01 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID = 0x02 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN = 0x03 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR = 0x04 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING = 0x06 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED = 0x07 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_KEY_ALGORITHM_NOT_ACCEPTED = 0x08 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE = 0x09 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION = 0x0a ;
/****
* #define AUTHSSL_DEBUG 1
@ -815,7 +820,11 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
ASN1_BIT_STRING *signature = const_cast<ASN1_BIT_STRING*>(tmp_signature);
#endif
//EVP_PKEY *pkey = NULL;
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
const EVP_MD *type = EVP_sha256();
#else
const EVP_MD *type = EVP_sha1();
#endif
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
int inl=0,hashoutl=0;
@ -855,44 +864,57 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
inl=i2d(data,NULL);
unsigned char *buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
unsigned char *p=NULL;
i2d(data,&buf_in);
#else
unsigned char *buf_in=NULL;
inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info
#endif
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
sigoutl=2048; // hashoutl; //EVP_PKEY_size(pkey);
unsigned char *buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl);
if ((buf_in == NULL) || (buf_sigout == NULL))
{
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
goto err;
}
std::cerr << "Buffers Allocated" << std::endl;
/* NOW Sign via GPG Functions */
if (!AuthGPG::getAuthGPG()->SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()"))
{
sigoutl = 0;
goto err;
}
#else
hashoutl=EVP_MD_size(type);
unsigned char *buf_hashout=(unsigned char *)OPENSSL_malloc((unsigned int)hashoutl);
sigoutl=2048; // hashoutl; //EVP_PKEY_size(pkey);
unsigned char *buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl);
if ((buf_in == NULL) || (buf_hashout == NULL) || (buf_sigout == NULL))
{
hashoutl=0;
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
goto err;
}
if((buf_hashout == NULL) || (buf_sigout == NULL))
{
hashoutl=0;
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
goto err;
}
std::cerr << "Buffers Allocated" << std::endl;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
p=buf_in;
i2d(data,&p);
#endif
/* data in buf_in, ready to be hashed */
EVP_DigestInit_ex(ctx,type, NULL);
EVP_DigestUpdate(ctx,(unsigned char *)buf_in,inl);
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout,
(unsigned int *)&hashoutl))
{
hashoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
goto err;
}
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout, (unsigned int *)&hashoutl))
{
hashoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
goto err;
}
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
/* NOW Sign via GPG Functions */
if (!AuthGPG::getAuthGPG()->SignDataBin(buf_hashout, hashoutl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()"))
@ -900,6 +922,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
sigoutl = 0;
goto err;
}
#endif
std::cerr << "Buffer Sizes: in: " << inl;
std::cerr << " HashOut: " << hashoutl;
@ -926,6 +949,14 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
EVP_MD_CTX_destroy(ctx) ;
// debug
{
int pkey_nid = OBJ_obj2nid(x509->cert_info->key->algor->algorithm);
const char* sslbuf = OBJ_nid2ln(pkey_nid);
std::cerr << "Signature hash algorithm: " << sslbuf << std::endl;
}
return x509;
/* XXX CLEANUP */
@ -1038,11 +1069,13 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
p=buf_in;
i2d(data,&p);
#endif
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
/* data in buf_in, ready to be hashed */
EVP_DigestInit_ex(ctx,type, NULL);
EVP_DigestUpdate(ctx,(unsigned char *)buf_in,inl);
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout,
(unsigned int *)&hashoutl))
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout, (unsigned int *)&hashoutl))
{
hashoutl=0;
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
@ -1052,14 +1085,15 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
#ifdef AUTHSSL_DEBUG
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
#endif
#endif
/* copy data into signature */
if(sigoutl < signature->length)
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
}
if(sigoutl < signature->length)
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
}
sigoutl = signature->length;
memmove(buf_sigout, signature->data, sigoutl);
@ -1069,10 +1103,73 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
std::cerr << "AuthSSLimpl::AuthX509() verifying the gpg sig with keyprint : " << pd.fpr << std::endl;
std::cerr << "Sigoutl = " << sigoutl << std::endl ;
std::cerr << "pd.fpr = " << pd.fpr << std::endl ;
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
std::cerr << "hashoutl = " << hashoutl << std::endl ;
#endif
#endif
// Take a early look at signature parameters. In particular we dont accept signatures with unsecure hash algorithms.
{
PGPSignatureInfo signature_info ;
PGPKeyManagement::parseSignature(buf_sigout,sigoutl,signature_info) ;
if(signature_info.signature_version != PGP_PACKET_TAG_SIGNATURE_VERSION_V4)
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION ;
return false ;
}
switch(signature_info.signature_type)
{
case PGP_PACKET_TAG_SIGNATURE_TYPE_STANDALONE_SIG :
break ;
case PGP_PACKET_TAG_SIGNATURE_TYPE_CANONICAL_TEXT :
case PGP_PACKET_TAG_SIGNATURE_TYPE_BINARY_DOCUMENT :
case PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN :
default:
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE ;
return false ;
}
switch(signature_info.hash_algorithm)
{
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA1 :
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA256:
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA512:
break ;
// We dont accept signatures with unknown or week hash algorithms.
case PGP_PACKET_TAG_HASH_ALGORITHM_MD5:
case PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN:
default:
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED ;
return false ;
}
switch(signature_info.public_key_algorithm)
{
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_ES :
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_S :
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_DSA :
break ;
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_E :
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN:
default:
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED ;
return false ;
}
}
// passed, verify the signature itself
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
if (!AuthGPG::getAuthGPG()->VerifySignBin(buf_in, inl, buf_sigout, (unsigned int) sigoutl, pd.fpr)) {
#else
if (!AuthGPG::getAuthGPG()->VerifySignBin(buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl, pd.fpr)) {
#endif
sigoutl = 0;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err;

View File

@ -348,7 +348,10 @@ typedef enum
// SHA1 Hash Size \todo is this the same as OPS_CHECKHASH_SIZE??
#define OPS_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
#define OPS_SHA224_HASH_SIZE SHA224_DIGEST_LENGTH
#define OPS_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH
#define OPS_SHA384_HASH_SIZE SHA384_DIGEST_LENGTH
#define OPS_SHA512_HASH_SIZE SHA512_DIGEST_LENGTH
// Max hash size
#define OPS_MAX_HASH_SIZE 64

View File

@ -216,8 +216,49 @@ static ops_boolean_t rsa_sign(ops_hash_t *hash, const ops_rsa_public_key_t *rsa,
unsigned t;
BIGNUM *bn;
int plen ;
unsigned int hash_length ;
unsigned char *prefix ;
switch(hash->algorithm)
{
case OPS_HASH_SHA1: hashsize=OPS_SHA1_HASH_SIZE+sizeof prefix_sha1;
hash_length=OPS_SHA1_HASH_SIZE ;
prefix = prefix_sha1;
plen = sizeof prefix_sha1 ;
break ;
case OPS_HASH_SHA224: hashsize=OPS_SHA224_HASH_SIZE+sizeof prefix_sha224;
hash_length=OPS_SHA224_HASH_SIZE ;
prefix = prefix_sha224;
plen = sizeof prefix_sha224 ;
break ;
case OPS_HASH_SHA256: hashsize=OPS_SHA256_HASH_SIZE+sizeof prefix_sha256;
hash_length=OPS_SHA256_HASH_SIZE ;
prefix = prefix_sha256;
plen = sizeof prefix_sha256 ;
break ;
case OPS_HASH_SHA384: hashsize=OPS_SHA384_HASH_SIZE+sizeof prefix_sha384;
hash_length=OPS_SHA384_HASH_SIZE ;
prefix = prefix_sha384;
plen = sizeof prefix_sha384 ;
break ;
case OPS_HASH_SHA512: hashsize=OPS_SHA512_HASH_SIZE+sizeof prefix_sha512;
hash_length=OPS_SHA512_HASH_SIZE ;
prefix = prefix_sha512;
plen = sizeof prefix_sha512 ;
break ;
case OPS_HASH_MD5: fprintf(stderr,"(insecure) MD5+RSA signatures not supported in RSA sign") ;
return ops_false ;
default: fprintf(stderr,"Hash algorithm %d not supported in RSA sign",hash->algorithm) ;
return ops_false ;
}
// XXX: we assume hash is sha-1 for now
hashsize=20+sizeof prefix_sha1;
keysize=BN_num_bytes(rsa->n);
@ -240,12 +281,12 @@ static ops_boolean_t rsa_sign(ops_hash_t *hash, const ops_rsa_public_key_t *rsa,
hashbuf[n]=0xff;
hashbuf[n++]=0;
memcpy(&hashbuf[n], prefix_sha1, sizeof prefix_sha1);
n+=sizeof prefix_sha1;
memcpy(&hashbuf[n], prefix, plen);
n+=plen;
t=hash->finish(hash, &hashbuf[n]);
if(t != 20)
if(t != hash_length)
{
fprintf(stderr,"Wrong hash size. Should be 20! can't sign.") ;
return ops_false ;
@ -1376,12 +1417,13 @@ void example(const ops_secret_key_t *skey)
\endcode
*/
ops_memory_t* ops_sign_buf(const void* input, const size_t input_len,
const ops_sig_type_t sig_type,
const ops_secret_key_t *skey,
const ops_boolean_t use_armour,
ops_boolean_t include_data,
ops_boolean_t include_creation_time,
ops_boolean_t include_key_id)
const ops_sig_type_t sig_type,
const ops_hash_algorithm_t hash_algorithm,
const ops_secret_key_t *skey,
const ops_boolean_t use_armour,
ops_boolean_t include_data,
ops_boolean_t include_creation_time,
ops_boolean_t include_key_id)
{
// \todo allow choice of hash algorithams
// enforce use of SHA1 for now
@ -1392,7 +1434,7 @@ ops_memory_t* ops_sign_buf(const void* input, const size_t input_len,
ops_create_info_t *cinfo=NULL;
ops_memory_t *mem=ops_memory_new();
ops_hash_algorithm_t hash_alg=OPS_HASH_SHA1;
ops_hash_algorithm_t hash_alg=hash_algorithm ;
ops_literal_data_type_t ld_type;
ops_hash_t* hash=NULL;

View File

@ -90,7 +90,7 @@ void ops_signature_add_primary_user_id(ops_create_signature_t *sig,
ops_boolean_t ops_sign_file_as_cleartext(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t overwrite);
ops_boolean_t ops_sign_buf_as_cleartext(const char* input, const size_t len, ops_memory_t** output, const ops_secret_key_t *skey);
ops_boolean_t ops_sign_file(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t use_armour, const ops_boolean_t overwrite);
ops_memory_t * ops_sign_buf(const void* input, const size_t input_len, const ops_sig_type_t sig_type, const ops_secret_key_t *skey, const ops_boolean_t use_armour,ops_boolean_t include_data,ops_boolean_t include_creation_time,ops_boolean_t include_key_id);
ops_memory_t * ops_sign_buf(const void* input, const size_t input_len, const ops_sig_type_t sig_type, const ops_hash_algorithm_t hash_algorithm, const ops_secret_key_t *skey, const ops_boolean_t use_armour, ops_boolean_t include_data, ops_boolean_t include_creation_time, ops_boolean_t include_key_id);
ops_boolean_t ops_writer_push_signed(ops_create_info_t *cinfo, const ops_sig_type_t sig_type, const ops_secret_key_t *skey);
#endif