summaryrefslogtreecommitdiffstats
path: root/g10/pkclist.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/pkclist.c')
-rw-r--r--g10/pkclist.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/g10/pkclist.c b/g10/pkclist.c
index dbbcbbdd8..4e58f125c 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -512,3 +512,102 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage )
}
+/****************
+ * Return -1 if we could not find an algorithm.
+ */
+int
+select_algo_from_prefs( PK_LIST pk_list, int preftype )
+{
+ PK_LIST pkr;
+ u32 bits[8];
+ byte *pref = NULL;
+ size_t npref;
+ int i, j;
+ int compr_hack=0;
+ int any;
+
+ if( !pk_list )
+ return -1;
+
+ memset( bits, ~0, 8 * sizeof *bits );
+ for( pkr = pk_list; pkr; pkr = pkr->next ) {
+ u32 mask[8];
+
+ memset( mask, 0, 8 * sizeof *mask );
+ if( !pkr->pk->local_id )
+ BUG(); /* if this occurs, we can use get_ownertrust to set it */
+ if( preftype == PREFTYPE_SYM )
+ bits[0] = (1<<2); /* 3DES is implicitly there */
+ m_free(pref);
+ pref = get_pref_data( pkr->pk->local_id, pkr->pk->namehash, &npref);
+ any = 0;
+ if( pref ) {
+ /*log_hexdump("raw: ", pref, npref );*/
+ for(i=0; i+1 < npref; i+=2 ) {
+ if( pref[i] == preftype ) {
+ mask[pref[i+1]/32] |= 1 << (pref[i+1]%32);
+ any = 1;
+ }
+ }
+ }
+ if( (!pref || !any) && preftype == PREFTYPE_COMPR ) {
+ mask[0] |= 3; /* asume no_compression and old pgp */
+ compr_hack = 1;
+ }
+
+ /*log_debug("mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
+ (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
+ (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);*/
+ for(i=0; i < 8; i++ )
+ bits[i] &= mask[i];
+ /*log_debug("bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
+ (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
+ (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);*/
+ }
+ /* usable algorithms are now in bits
+ * We now use the last key from pk_list to select
+ * the algorithm we want to use. there are no
+ * preferences for the last key, we select the one
+ * corresponding to first set bit.
+ */
+ i = -1;
+ any = 0;
+ if( pref ) {
+ for(j=0; j+1 < npref; j+=2 ) {
+ if( pref[j] == preftype ) {
+ any = 1;
+ if( (bits[pref[j+1]/32] & (1<<(pref[j+1]%32))) ) {
+ i = pref[j+1];
+ break;
+ }
+ }
+ }
+ }
+ if( !pref || !any ) {
+ for(j=0; j < 256; j++ )
+ if( (bits[j/32] & (1<<(j%32))) ) {
+ i = j;
+ break;
+ }
+ }
+ /*log_debug("prefs of type %d: selected %d\n", preftype, i );*/
+ if( compr_hack && !i ) {
+ /* selected no compression, but we should check whether
+ * algorithm 1 is also available (the ordering is not relevant
+ * in this case). */
+ if( bits[0] & (1<<1) )
+ i = 1; /* yep; we can use compression algo 1 */
+ }
+
+ if( preftype == PREFTYPE_SYM && i == CIPHER_ALGO_3DES ) {
+ i = CIPHER_ALGO_BLOWFISH;
+ if( opt.verbose )
+ log_info("replacing 3DES by Blowfish\n");
+ }
+
+
+ m_free(pref);
+ return i;
+}
+
+