fixed signature verification

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-OpenPGP@5122 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2012-04-26 19:37:15 +00:00
parent 0587216350
commit afc23f39c8
3 changed files with 653 additions and 595 deletions

View File

@ -215,21 +215,24 @@ void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_
while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next += namestring[i] ; ++i ;} while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next += namestring[i] ; ++i ;}
while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { next += namestring[i] ; ++i ;} while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { next += namestring[i] ; ++i ;}
if(i< namestring.length())
{
std::string& next2 = (namestring[i] == '(')?cert._comment:cert._email ; std::string& next2 = (namestring[i] == '(')?cert._comment:cert._email ;
++i ; ++i ;
next2 = "" ; next2 = "" ;
while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next2 += namestring[i] ; ++i ;} while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next2 += namestring[i] ; ++i ;}
} }
}
cert._trustLvl = 1 ; // to be setup accordingly cert._trustLvl = 1 ; // to be setup accordingly
cert._key_index = index ; cert._key_index = index ;
cert._flags = 0 ;
ops_fingerprint_t f ; ops_fingerprint_t f ;
ops_fingerprint(&f,&keydata->key.pkey) ; ops_fingerprint(&f,&keydata->key.pkey) ;
cert._fpr = PGPFingerprintType(f.fingerprint) ; cert._fpr = PGPFingerprintType(f.fingerprint) ;
std::cerr << __PRETTY_FUNCTION__ << ": unfinished!!" << std::endl;
} }
PGPHandler::~PGPHandler() PGPHandler::~PGPHandler()
@ -666,7 +669,7 @@ bool PGPHandler::getKeyFingerprint(const PGPIdType& id,PGPFingerprintType& fp) c
return true ; return true ;
} }
bool PGPHandler::VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) bool PGPHandler::VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint)
{ {
PGPIdType id = PGPIdType::fromFingerprint_hex(key_fingerprint.toStdString()) ; PGPIdType id = PGPIdType::fromFingerprint_hex(key_fingerprint.toStdString()) ;
const ops_keydata_t *key = getPublicKey(id) ; const ops_keydata_t *key = getPublicKey(id) ;
@ -689,14 +692,11 @@ bool PGPHandler::VerifySignBin(const void *data, uint32_t data_len, unsigned cha
} }
std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << std::endl; std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << std::endl;
std::cerr << "Warning: signature code still unfinished!" << key_fingerprint.toStdString() << std::endl;
ops_signature_t signature ; std::cerr << "Verifying signature of length " << std::dec << sign_len << ", literal_length = " << literal_data_length << std::endl;
// ops_signature_add_data(&signature,sign,sign_len) ; std::cerr << "Data: " << (char *)sign << std::endl;
// ops_boolean_t valid=check_binary_signature(data_len,data,signature,pkey) ; return ops_validate_detached_signature(literal_data,literal_data_length,sign,sign_len,key) ;
return false ;
} }
void PGPHandler::setAcceptConnexion(const PGPIdType& id,bool b) void PGPHandler::setAcceptConnexion(const PGPIdType& id,bool b)

View File

@ -98,5 +98,7 @@ ops_validate_key_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cb
ops_boolean_t ops_validate_file(ops_validate_result_t* result, const char* filename, const int armoured, const ops_keyring_t* keyring); ops_boolean_t ops_validate_file(ops_validate_result_t* result, const char* filename, const int armoured, const ops_keyring_t* keyring);
ops_boolean_t ops_validate_mem(ops_validate_result_t *result, ops_memory_t* mem, const int armoured, const ops_keyring_t* keyring); ops_boolean_t ops_validate_mem(ops_validate_result_t *result, ops_memory_t* mem, const int armoured, const ops_keyring_t* keyring);
ops_boolean_t ops_validate_detached_signature(const void *literal_data, unsigned int literal_data_length, const unsigned char *signature_packet, unsigned int signature_packet_length,const ops_keydata_t *signers_key) ;
// EOF // EOF

View File

@ -41,7 +41,7 @@ static ops_boolean_t check_binary_signature(const unsigned len,
const unsigned char *data, const unsigned char *data,
const ops_signature_t *sig, const ops_signature_t *sig,
const ops_public_key_t *signer __attribute__((unused))) const ops_public_key_t *signer __attribute__((unused)))
{ {
// Does the signed hash match the given hash? // Does the signed hash match the given hash?
int n=0; int n=0;
@ -88,12 +88,12 @@ static ops_boolean_t check_binary_signature(const unsigned len,
// return ops_false; // return ops_false;
return ops_check_signature(hashout,n,sig,signer); return ops_check_signature(hashout,n,sig,signer);
} }
static int keydata_reader(void *dest,size_t length,ops_error_t **errors, static int keydata_reader(void *dest,size_t length,ops_error_t **errors,
ops_reader_info_t *rinfo, ops_reader_info_t *rinfo,
ops_parse_cb_info_t *cbinfo) ops_parse_cb_info_t *cbinfo)
{ {
validate_reader_arg_t *arg=ops_reader_get_arg(rinfo); validate_reader_arg_t *arg=ops_reader_get_arg(rinfo);
OPS_USED(errors); OPS_USED(errors);
@ -114,23 +114,23 @@ static int keydata_reader(void *dest,size_t length,ops_error_t **errors,
arg->offset+=length; arg->offset+=length;
return length; return length;
} }
static void free_signature_info(ops_signature_info_t *sig) static void free_signature_info(ops_signature_info_t *sig)
{ {
free (sig->v4_hashed_data); free (sig->v4_hashed_data);
free (sig); free (sig);
} }
static void copy_signature_info(ops_signature_info_t* dst, const ops_signature_info_t* src) static void copy_signature_info(ops_signature_info_t* dst, const ops_signature_info_t* src)
{ {
memcpy(dst,src,sizeof *src); memcpy(dst,src,sizeof *src);
dst->v4_hashed_data=ops_mallocz(src->v4_hashed_data_length); dst->v4_hashed_data=ops_mallocz(src->v4_hashed_data_length);
memcpy(dst->v4_hashed_data,src->v4_hashed_data,src->v4_hashed_data_length); memcpy(dst->v4_hashed_data,src->v4_hashed_data,src->v4_hashed_data_length);
} }
static void add_sig_to_valid_list(ops_validate_result_t * result, const ops_signature_info_t* sig) static void add_sig_to_valid_list(ops_validate_result_t * result, const ops_signature_info_t* sig)
{ {
size_t newsize; size_t newsize;
size_t start; size_t start;
@ -147,10 +147,10 @@ static void add_sig_to_valid_list(ops_validate_result_t * result, const ops_sign
// copy key ptr to array // copy key ptr to array
start=(sizeof *sig) * (result->valid_count-1); start=(sizeof *sig) * (result->valid_count-1);
copy_signature_info(result->valid_sigs+start,sig); copy_signature_info(result->valid_sigs+start,sig);
} }
static void add_sig_to_invalid_list(ops_validate_result_t * result, const ops_signature_info_t *sig) static void add_sig_to_invalid_list(ops_validate_result_t * result, const ops_signature_info_t *sig)
{ {
size_t newsize; size_t newsize;
size_t start; size_t start;
@ -167,10 +167,10 @@ static void add_sig_to_invalid_list(ops_validate_result_t * result, const ops_si
// copy key ptr to array // copy key ptr to array
start=(sizeof *sig) * (result->invalid_count-1); start=(sizeof *sig) * (result->invalid_count-1);
copy_signature_info(result->invalid_sigs+start, sig); copy_signature_info(result->invalid_sigs+start, sig);
} }
static void add_sig_to_unknown_list(ops_validate_result_t * result, const ops_signature_info_t *sig) static void add_sig_to_unknown_list(ops_validate_result_t * result, const ops_signature_info_t *sig)
{ {
size_t newsize; size_t newsize;
size_t start; size_t start;
@ -187,11 +187,11 @@ static void add_sig_to_unknown_list(ops_validate_result_t * result, const ops_si
// copy key id to array // copy key id to array
start=OPS_KEY_ID_SIZE * (result->unknown_signer_count-1); start=OPS_KEY_ID_SIZE * (result->unknown_signer_count-1);
copy_signature_info(result->unknown_sigs+start, sig); copy_signature_info(result->unknown_sigs+start, sig);
} }
ops_parse_cb_return_t ops_parse_cb_return_t
ops_validate_key_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) ops_validate_key_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
{ {
const ops_parser_content_union_t *content=&content_->content; const ops_parser_content_union_t *content=&content_->content;
validate_key_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); validate_key_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo);
ops_error_t **errors=ops_parse_cb_get_errors(cbinfo); ops_error_t **errors=ops_parse_cb_get_errors(cbinfo);
@ -337,11 +337,11 @@ ops_validate_key_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cb
break; break;
} }
return OPS_RELEASE_MEMORY; return OPS_RELEASE_MEMORY;
} }
ops_parse_cb_return_t ops_parse_cb_return_t
validate_data_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) validate_data_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
{ {
const ops_parser_content_union_t *content=&content_->content; const ops_parser_content_union_t *content=&content_->content;
validate_data_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); validate_data_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo);
ops_error_t **errors=ops_parse_cb_get_errors(cbinfo); ops_error_t **errors=ops_parse_cb_get_errors(cbinfo);
@ -469,13 +469,13 @@ validate_data_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinf
break; break;
} }
return OPS_RELEASE_MEMORY; return OPS_RELEASE_MEMORY;
} }
static void keydata_destroyer(ops_reader_info_t *rinfo) static void keydata_destroyer(ops_reader_info_t *rinfo)
{ free(ops_reader_get_arg(rinfo)); } { free(ops_reader_get_arg(rinfo)); }
void ops_keydata_reader_set(ops_parse_info_t *pinfo,const ops_keydata_t *key) void ops_keydata_reader_set(ops_parse_info_t *pinfo,const ops_keydata_t *key)
{ {
validate_reader_arg_t *arg=malloc(sizeof *arg); validate_reader_arg_t *arg=malloc(sizeof *arg);
memset(arg,'\0',sizeof *arg); memset(arg,'\0',sizeof *arg);
@ -485,7 +485,7 @@ void ops_keydata_reader_set(ops_parse_info_t *pinfo,const ops_keydata_t *key)
arg->offset=0; arg->offset=0;
ops_reader_set(pinfo,keydata_reader,keydata_destroyer,arg); ops_reader_set(pinfo,keydata_reader,keydata_destroyer,arg);
} }
/** /**
* \ingroup HighLevel_Verify * \ingroup HighLevel_Verify
@ -494,12 +494,12 @@ void ops_keydata_reader_set(ops_parse_info_t *pinfo,const ops_keydata_t *key)
* \return ops_false if any invalid signatures or unknown signers or no valid signatures; else ops_true * \return ops_false if any invalid signatures or unknown signers or no valid signatures; else ops_true
*/ */
ops_boolean_t validate_result_status(ops_validate_result_t* result) ops_boolean_t validate_result_status(ops_validate_result_t* result)
{ {
if (result->invalid_count || result->unknown_signer_count || !result->valid_count) if (result->invalid_count || result->unknown_signer_count || !result->valid_count)
return ops_false; return ops_false;
else else
return ops_true; return ops_true;
} }
/** /**
* \ingroup HighLevel_Verify * \ingroup HighLevel_Verify
@ -513,9 +513,9 @@ ops_boolean_t validate_result_status(ops_validate_result_t* result)
* \sa ops_validate_result_free() * \sa ops_validate_result_free()
Example Code: Example Code:
\code \code
void example(const ops_keydata_t* key, const ops_keyring_t *keyring) void example(const ops_keydata_t* key, const ops_keyring_t *keyring)
{ {
ops_validate_result_t *result=NULL; ops_validate_result_t *result=NULL;
if (ops_validate_key_signatures(result, key, keyring, callback_cmd_get_passphrase_from_cmdline)==ops_true) if (ops_validate_key_signatures(result, key, keyring, callback_cmd_get_passphrase_from_cmdline)==ops_true)
printf("OK"); printf("OK");
@ -526,15 +526,15 @@ void example(const ops_keydata_t* key, const ops_keyring_t *keyring)
result->invalid_count, result->invalid_count,
result->unknown_signer_count); result->unknown_signer_count);
ops_validate_result_free(result); ops_validate_result_free(result);
} }
\endcode \endcode
*/ */
ops_boolean_t ops_validate_key_signatures(ops_validate_result_t *result,const ops_keydata_t *key, ops_boolean_t ops_validate_key_signatures(ops_validate_result_t *result,const ops_keydata_t *key,
const ops_keyring_t *keyring, const ops_keyring_t *keyring,
ops_parse_cb_return_t cb_get_passphrase (const ops_parser_content_t *, ops_parse_cb_info_t *) ops_parse_cb_return_t cb_get_passphrase (const ops_parser_content_t *, ops_parse_cb_info_t *)
) )
{ {
ops_parse_info_t *pinfo; ops_parse_info_t *pinfo;
validate_key_cb_arg_t carg; validate_key_cb_arg_t carg;
@ -569,7 +569,7 @@ ops_boolean_t ops_validate_key_signatures(ops_validate_result_t *result,const op
return ops_false; return ops_false;
else else
return ops_true; return ops_true;
} }
/** /**
\ingroup HighLevel_Verify \ingroup HighLevel_Verify
@ -578,28 +578,28 @@ ops_boolean_t ops_validate_key_signatures(ops_validate_result_t *result,const op
\param cb_get_passphrase Callback to use to get passphrase \param cb_get_passphrase Callback to use to get passphrase
\note It is the caller's responsibility to free result after use. \note It is the caller's responsibility to free result after use.
\sa ops_validate_result_free() \sa ops_validate_result_free()
*/ */
ops_boolean_t ops_validate_all_signatures(ops_validate_result_t *result, ops_boolean_t ops_validate_all_signatures(ops_validate_result_t *result,
const ops_keyring_t *ring, const ops_keyring_t *ring,
ops_parse_cb_return_t cb_get_passphrase (const ops_parser_content_t *, ops_parse_cb_info_t *) ops_parse_cb_return_t cb_get_passphrase (const ops_parser_content_t *, ops_parse_cb_info_t *)
) )
{ {
int n; int n;
memset(result,'\0',sizeof *result); memset(result,'\0',sizeof *result);
for(n=0 ; n < ring->nkeys ; ++n) for(n=0 ; n < ring->nkeys ; ++n)
ops_validate_key_signatures(result,&ring->keys[n],ring, cb_get_passphrase); ops_validate_key_signatures(result,&ring->keys[n],ring, cb_get_passphrase);
return validate_result_status(result); return validate_result_status(result);
} }
/** /**
\ingroup HighLevel_Verify \ingroup HighLevel_Verify
\brief Frees validation result and associated memory \brief Frees validation result and associated memory
\param result Struct to be freed \param result Struct to be freed
\note Must be called after validation functions \note Must be called after validation functions
*/ */
void ops_validate_result_free(ops_validate_result_t *result) void ops_validate_result_free(ops_validate_result_t *result)
{ {
if (!result) if (!result)
return; return;
@ -612,7 +612,7 @@ void ops_validate_result_free(ops_validate_result_t *result)
free(result); free(result);
result=NULL; result=NULL;
} }
/** /**
\ingroup HighLevel_Verify \ingroup HighLevel_Verify
@ -626,29 +626,29 @@ void ops_validate_result_free(ops_validate_result_t *result)
have passed, failed and not been recognised. have passed, failed and not been recognised.
\note It is the caller's responsiblity to call ops_validate_result_free(result) after use. \note It is the caller's responsiblity to call ops_validate_result_free(result) after use.
Example code: Example code:
\code \code
void example(const char* filename, const int armoured, const ops_keyring_t* keyring) void example(const char* filename, const int armoured, const ops_keyring_t* keyring)
{ {
ops_validate_result_t* result=ops_mallocz(sizeof *result); ops_validate_result_t* result=ops_mallocz(sizeof *result);
if (ops_validate_file(result, filename, armoured, keyring)==ops_true) if (ops_validate_file(result, filename, armoured, keyring)==ops_true)
{ {
printf("OK"); printf("OK");
// look at result for details of keys with good signatures // look at result for details of keys with good signatures
} }
else else
{ {
printf("ERR"); printf("ERR");
// look at result for details of failed signatures or unknown signers // look at result for details of failed signatures or unknown signers
} }
ops_validate_result_free(result); ops_validate_result_free(result);
} }
\endcode \endcode
*/ */
ops_boolean_t ops_validate_file(ops_validate_result_t *result, const char* filename, const int armoured, const ops_keyring_t* keyring) ops_boolean_t ops_validate_file(ops_validate_result_t *result, const char* filename, const int armoured, const ops_keyring_t* keyring)
{ {
ops_parse_info_t *pinfo=NULL; ops_parse_info_t *pinfo=NULL;
validate_data_cb_arg_t validate_arg; validate_data_cb_arg_t validate_arg;
@ -689,7 +689,7 @@ ops_boolean_t ops_validate_file(ops_validate_result_t *result, const char* filen
ops_teardown_file_read(pinfo, fd); ops_teardown_file_read(pinfo, fd);
return validate_result_status(result); return validate_result_status(result);
} }
/** /**
\ingroup HighLevel_Verify \ingroup HighLevel_Verify
@ -702,10 +702,10 @@ ops_boolean_t ops_validate_file(ops_validate_result_t *result, const char* filen
\note After verification, result holds the details of all keys which \note After verification, result holds the details of all keys which
have passed, failed and not been recognised. have passed, failed and not been recognised.
\note It is the caller's responsiblity to call ops_validate_result_free(result) after use. \note It is the caller's responsiblity to call ops_validate_result_free(result) after use.
*/ */
ops_boolean_t ops_validate_mem(ops_validate_result_t *result, ops_memory_t* mem, const int armoured, const ops_keyring_t* keyring) ops_boolean_t ops_validate_mem(ops_validate_result_t *result, ops_memory_t* mem, const int armoured, const ops_keyring_t* keyring)
{ {
ops_parse_info_t *pinfo=NULL; ops_parse_info_t *pinfo=NULL;
validate_data_cb_arg_t validate_arg; validate_data_cb_arg_t validate_arg;
@ -742,6 +742,62 @@ ops_boolean_t ops_validate_mem(ops_validate_result_t *result, ops_memory_t* mem,
ops_teardown_memory_read(pinfo, mem); ops_teardown_memory_read(pinfo, mem);
return validate_result_status(result); return validate_result_status(result);
} }
ops_boolean_t ops_validate_detached_signature(const void *literal_data, unsigned int literal_data_length, const unsigned char *signature_packet, unsigned int signature_packet_length,const ops_keydata_t *signers_key)
{
ops_validate_result_t *result = (ops_validate_result_t*)ops_mallocz(sizeof(ops_validate_result_t));
ops_memory_t *mem = ops_memory_new() ;
ops_memory_add(mem,signature_packet,signature_packet_length) ;
ops_parse_info_t *pinfo=NULL;
validate_data_cb_arg_t validate_arg;
ops_setup_memory_read(&pinfo, mem, &validate_arg, validate_data_cb, ops_true);
// Set verification reader and handling options
ops_keyring_t tmp_keyring ;
tmp_keyring.nkeys = 1 ;
tmp_keyring.nkeys_allocated = 1 ;
tmp_keyring.keys = signers_key ;
memset(&validate_arg,'\0',sizeof validate_arg);
validate_arg.result=result;
validate_arg.keyring=&tmp_keyring;
int length = 8192 ;
if(literal_data_length < length)
length = literal_data_length ;
memcpy(validate_arg.data.literal_data_body.data, literal_data, length) ;
validate_arg.data.literal_data_body.length = length ;
// Note: Coverity incorrectly reports an error that carg.rarg
// is never used.
validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo);
//if (armoured)
// ops_reader_push_dearmour(pinfo);
// Do the verification
ops_parse(pinfo);
printf("valid=%d, invalid=%d, unknown=%d\n", result->valid_count, result->invalid_count, result->unknown_signer_count);
// Tidy up
//if (armoured)
// ops_reader_pop_dearmour(pinfo);
ops_teardown_memory_read(pinfo, mem);
ops_boolean_t res = validate_result_status(result);
ops_validate_result_free(result) ;
return res ;
}
// eof // eof