diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index 72e49c36e..213833087 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -164,6 +164,39 @@ ops_keyring_t *PGPHandler::allocateOPSKeyring() return kr ; } +ops_parse_cb_return_t cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)// __attribute__((unused))) +{ + const ops_parser_content_union_t *content=&content_->content; + // validate_key_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); + // ops_error_t **errors=ops_parse_cb_get_errors(cbinfo); + + bool prev_was_bad = false ; + + switch(content_->tag) + { + case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: prev_was_bad = true ; + case OPS_PARSER_CMD_GET_SK_PASSPHRASE: + { + std::string passwd; + std::string uid_hint = std::string((const char *)cbinfo->cryptinfo.keydata->uids[0].user_id) ; + uid_hint += "(" + PGPIdType(cbinfo->cryptinfo.keydata->key_id).toStdString()+")" ; + + passwd = PGPHandler::passphraseCallback()(NULL,uid_hint.c_str(),NULL,prev_was_bad) ; +// if (rsicontrol->getNotify().askForPassword(uid_hint, prev_was_bad, passwd) == false) +// return OPS_RELEASE_MEMORY; + + *(content->secret_key_passphrase.passphrase)= (char *)ops_mallocz(passwd.length()+1) ; + memcpy(*(content->secret_key_passphrase.passphrase),passwd.c_str(),passwd.length()) ; + return OPS_KEEP_MEMORY; + } + break; + + default: + break; + } + + return OPS_RELEASE_MEMORY; +} void PGPHandler::setPassphraseCallback(PassphraseCallback cb) { _passphrase_callback = cb ; @@ -192,10 +225,18 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring) int i=0 ; while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) { - initCertificateInfo(_public_keyring_map[ PGPIdType(keydata->key_id).toStdString() ],keydata,i) ; + PGPCertificateInfo& cert(_public_keyring_map[ PGPIdType(keydata->key_id).toStdString() ]) ; + + // Init all certificates. + + initCertificateInfo(cert,keydata,i) ; + + // Validate signatures. + + validateAndUpdateSignatures(cert,keydata) ; + ++i ; } - std::cerr << "Pubring read successfully." << std::endl; if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str())) @@ -209,6 +250,7 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring) } std::cerr << "Secring read successfully." << std::endl; + } void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) @@ -249,16 +291,21 @@ void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_ ops_fingerprint(&f,&keydata->key.pkey) ; cert._fpr = PGPFingerprintType(f.fingerprint) ; +} + +void PGPHandler::validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) +{ + ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + ops_boolean_t res = ops_validate_key_signatures(result,keydata,_pubring,cb_get_passphrase) ; // Parse signers. // - - for(size_t i=0;insigs;++i) - { - cert.signers.insert(std::string((const char *)keydata->sigs[i].userid->user_id)) ; - std::cerr << "Signature data packet size = " << keydata->sigs[i].packet->length << std::endl; - } + if(result != NULL) + for(size_t i=0;ivalid_count;++i) + cert.signers.insert(PGPIdType(result->valid_sigs[i].signer_id).toStdString()) ; + + ops_validate_result_free(result) ; } PGPHandler::~PGPHandler() @@ -338,39 +385,7 @@ bool PGPHandler::availableGPGCertificatesWithPrivateKeys(std::list& i return true ; } -ops_parse_cb_return_t cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)// __attribute__((unused))) -{ - const ops_parser_content_union_t *content=&content_->content; - // validate_key_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); - // ops_error_t **errors=ops_parse_cb_get_errors(cbinfo); - bool prev_was_bad = false ; - - switch(content_->tag) - { - case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: prev_was_bad = true ; - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - { - std::string passwd; - std::string uid_hint = std::string((const char *)cbinfo->cryptinfo.keydata->uids[0].user_id) ; - uid_hint += "(" + PGPIdType(cbinfo->cryptinfo.keydata->key_id).toStdString()+")" ; - - passwd = PGPHandler::passphraseCallback()(NULL,uid_hint.c_str(),NULL,prev_was_bad) ; -// if (rsicontrol->getNotify().askForPassword(uid_hint, prev_was_bad, passwd) == false) -// return OPS_RELEASE_MEMORY; - - *(content->secret_key_passphrase.passphrase)= (char *)ops_mallocz(passwd.length()+1) ; - memcpy(*(content->secret_key_passphrase.passphrase),passwd.c_str(),passwd.length()) ; - return OPS_KEEP_MEMORY; - } - break; - - default: - break; - } - - return OPS_RELEASE_MEMORY; -} bool PGPHandler::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, PGPIdType& pgpId, std::string& errString) { @@ -432,6 +447,10 @@ bool PGPHandler::GeneratePGPCertificate(const std::string& name, const std::stri ops_keyring_free(tmp_keyring) ; free(tmp_keyring) ; + // 7 - validate own signature and update certificate. + + validateAndUpdateSignatures(_public_keyring_map[ pgpId.toStdString() ],getPublicKey(pgpId)) ; + return true ; } @@ -526,6 +545,7 @@ bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,PGPIdType addNewKeyToOPSKeyring(_pubring,*keydata) ; initCertificateInfo(_public_keyring_map[id.toStdString()],keydata,_pubring->nkeys-1) ; + validateAndUpdateSignatures(_public_keyring_map[id.toStdString()],keydata) ; } std::cerr << "Added the key in the main public keyring." << std::endl; diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h index c7b7ac644..44c30fd7c 100644 --- a/libretroshare/src/pgp/pgphandler.h +++ b/libretroshare/src/pgp/pgphandler.h @@ -135,6 +135,7 @@ class PGPHandler static PassphraseCallback passphraseCallback() { return _passphrase_callback ; } private: void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ; + void validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) ; const ops_keydata_t *getPublicKey(const PGPIdType&) const ; const ops_keydata_t *getSecretKey(const PGPIdType&) const ; diff --git a/openpgpsdk/src/accumulate.c b/openpgpsdk/src/accumulate.c index dac56e609..8c789eab0 100644 --- a/openpgpsdk/src/accumulate.c +++ b/openpgpsdk/src/accumulate.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "keyring_local.h" #include "parse_local.h" #include #include diff --git a/openpgpsdk/src/keyring.c b/openpgpsdk/src/keyring.c index 0e61a85c6..b4d2141cb 100644 --- a/openpgpsdk/src/keyring.c +++ b/openpgpsdk/src/keyring.c @@ -977,6 +977,18 @@ cb_keyring_read(const ops_parser_content_t *content_, return OPS_RELEASE_MEMORY; } +/** + \ingroup HighLevel_KeyringList + + \brief Saves keyring to specified file + + \param keyring Keyring to save + \param armoured Save in ascii armoured format + \param output filename + + \return ops_true is anything when ok +*/ + ops_boolean_t ops_write_keyring_to_file(const ops_keyring_t *keyring,ops_boolean_t armoured,const char *filename) { ops_create_info_t *info; @@ -994,8 +1006,9 @@ ops_boolean_t ops_write_keyring_to_file(const ops_keyring_t *keyring,ops_boolean ops_write_transferable_public_key(&keyring->keys[i],armoured,info) ; else { - fprintf(stderr, "ops_write_keyring: not writing key. Algorithm not handled: ") ; + fprintf(stdout, "ops_write_keyring: not writing key. Algorithm not handled: ") ; ops_print_public_keydata(&keyring->keys[i]); + fprintf(stdout, "\n") ; } ops_writer_close(info); diff --git a/openpgpsdk/src/openssl_crypto.c b/openpgpsdk/src/openssl_crypto.c index 6b48d2897..25f01816c 100644 --- a/openpgpsdk/src/openssl_crypto.c +++ b/openpgpsdk/src/openssl_crypto.c @@ -420,7 +420,16 @@ ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length, { fprintf(stderr,"ret=%d\n",ret); } - assert(ret >= 0); + + 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); diff --git a/openpgpsdk/src/signature.c b/openpgpsdk/src/signature.c index e24460484..d257e1bf4 100644 --- a/openpgpsdk/src/signature.c +++ b/openpgpsdk/src/signature.c @@ -408,6 +408,8 @@ ops_boolean_t ops_check_signature(const unsigned char *hash, unsigned length, case OPS_PKA_DSA: ret=ops_dsa_verify(hash, length, &sig->info.signature.dsa, &signer->key.dsa); +/* fprintf(stderr,"Cannot verify DSA signature. skipping.\n") ; + ret = ops_false ; */ break; case OPS_PKA_RSA: @@ -1237,6 +1239,7 @@ ops_boolean_t ops_sign_file(const char* input_filename, \param sig_type Signature type \param skey Secret Key \param use_armour Write armoured text, if set +\param include_data Includes the signed data in the output message. If not, creates a detached signature. \return New ops_memory_t struct containing signed text \note It is the caller's responsibility to call ops_memory_free(me) diff --git a/openpgpsdk/src/validate.c b/openpgpsdk/src/validate.c index da09218fe..450cec83c 100644 --- a/openpgpsdk/src/validate.c +++ b/openpgpsdk/src/validate.c @@ -146,7 +146,7 @@ static void add_sig_to_valid_list(ops_validate_result_t * result, const ops_sign // copy key ptr to array start=(sizeof *sig) * (result->valid_count-1); - copy_signature_info(result->valid_sigs+start,sig); + copy_signature_info(&result->valid_sigs[result->valid_count-1],sig); } static void add_sig_to_invalid_list(ops_validate_result_t * result, const ops_signature_info_t *sig) @@ -166,7 +166,7 @@ static void add_sig_to_invalid_list(ops_validate_result_t * result, const ops_si // copy key ptr to array start=(sizeof *sig) * (result->invalid_count-1); - copy_signature_info(result->invalid_sigs+start, sig); + copy_signature_info(&result->invalid_sigs[result->invalid_count-1],sig); } static void add_sig_to_unknown_list(ops_validate_result_t * result, const ops_signature_info_t *sig) @@ -186,7 +186,7 @@ static void add_sig_to_unknown_list(ops_validate_result_t * result, const ops_si // copy key id to array start=OPS_KEY_ID_SIZE * (result->unknown_signer_count-1); - copy_signature_info(result->unknown_sigs+start, sig); + copy_signature_info(&result->unknown_sigs[result->unknown_signer_count-1],sig); } ops_parse_cb_return_t @@ -752,6 +752,17 @@ ops_boolean_t ops_validate_mem(ops_validate_result_t *result, ops_memory_t* mem, return validate_result_status(result); } +/** + \ingroup HighLevel_Verify + \brief Verifies the signature in a detached signature data packet, given the literal data + \param literal_data Literal data that is signed + \param literal_data_length length of the literal data that is signed + \param signature_packet signature packet in binary PGP format + \param signature_packet_length length of the signature packet + \param signers_key Public key of the signer to check the signature for. + \return ops_true if signature validates successfully; ops_false if not + */ + 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)); @@ -769,7 +780,7 @@ ops_boolean_t ops_validate_detached_signature(const void *literal_data, unsigned ops_keyring_t tmp_keyring ; tmp_keyring.nkeys = 1 ; tmp_keyring.nkeys_allocated = 1 ; - tmp_keyring.keys = signers_key ; + tmp_keyring.keys = (ops_keydata_t *)signers_key ; // this is a const_cast, somehow memset(&validate_arg,'\0',sizeof validate_arg);