LCOV - code coverage report
Current view: top level - disco/keyguard - fd_keyguard_authorize.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 98 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #include "fd_keyguard.h"
       2             : #include "fd_keyguard_client.h"
       3             : 
       4             : struct fd_keyguard_sign_req {
       5             :   fd_keyguard_authority_t * authority;
       6             : };
       7             : 
       8             : typedef struct fd_keyguard_sign_req fd_keyguard_sign_req_t;
       9             : 
      10             : static int
      11             : fd_keyguard_authorize_vote_txn( fd_keyguard_authority_t const * authority,
      12             :                                 uchar const *                   data,
      13             :                                 ulong                           sz,
      14           0 :                                 int                             sign_type ) {
      15             :   /* FIXME Add vote transaction authorization here */
      16           0 :   (void)authority; (void)data; (void)sz; (void)sign_type;
      17           0 :   return 1;
      18           0 : }
      19             : 
      20             : static int
      21             : fd_keyguard_authorize_gossip( fd_keyguard_authority_t const * authority,
      22             :                               uchar const *                   data,
      23             :                               ulong                           sz,
      24           0 :                               int                             sign_type ) {
      25             :   /* FIXME Add gossip message authorization here */
      26           0 :   (void)authority; (void)data; (void)sz; (void)sign_type;
      27           0 :   return 1;
      28           0 : }
      29             : 
      30             : static int
      31             : fd_keyguard_authorize_ping( fd_keyguard_authority_t const * authority,
      32             :                             uchar const *                   data,
      33             :                             ulong                           sz,
      34           0 :                             int                             sign_type ) {
      35           0 :   (void)authority;
      36           0 :   if( sign_type != FD_KEYGUARD_SIGN_TYPE_SHA256_ED25519 ) return 0;
      37           0 :   if( sz != 48 ) return 0;
      38           0 :   if( 0!=memcmp( data, "SOLANA_PING_PONG", 16 ) ) return 0;
      39           0 :   return 1;
      40           0 : }
      41             : 
      42             : static int
      43             : fd_keyguard_authorize_gossip_prune( fd_keyguard_authority_t const * authority,
      44             :                                     uchar const *                   data,
      45             :                                     ulong                           sz,
      46           0 :                                     int                             sign_type ) {
      47           0 :   if( FD_UNLIKELY( sign_type != FD_KEYGUARD_SIGN_TYPE_ED25519 ) ) return 0;
      48             :   /* Prune messages always begin with the node's pubkey */
      49           0 :   if( sz<40UL ) return 0;
      50           0 :   if( 0!=memcmp( authority->identity_pubkey, data, 32 ) ) return 0;
      51           0 :   return 1;
      52           0 : }
      53             : 
      54             : static int
      55             : fd_keyguard_authorize_repair( fd_keyguard_authority_t const * authority,
      56             :                               uchar const *                   data,
      57             :                               ulong                           sz,
      58           0 :                               int                             sign_type ) {
      59             : 
      60           0 :   if( sign_type != FD_KEYGUARD_SIGN_TYPE_ED25519 ) return 0;
      61           0 :   if( sz<80 ) return 0;
      62             : 
      63           0 :   uint          discriminant = fd_uint_load_4( data );
      64           0 :   uchar const * sender       = data+4;
      65             : 
      66           0 :   if( discriminant< 8 ) return 0; /* window_index is min ID */
      67           0 :   if( discriminant>11 ) return 0; /* ancestor_hashes is max ID */
      68             : 
      69           0 :   if( 0!=memcmp( authority->identity_pubkey, sender, 32 ) ) return 0;
      70             : 
      71           0 :   return 1;
      72           0 : }
      73             : 
      74             : int
      75             : fd_keyguard_payload_authorize( fd_keyguard_authority_t const * authority,
      76             :                                uchar const *                   data,
      77             :                                ulong                           sz,
      78             :                                int                             role,
      79           0 :                                int                             sign_type ) {
      80             : 
      81           0 :   if( sz > FD_KEYGUARD_SIGN_REQ_MTU ) {
      82           0 :     FD_LOG_WARNING(( "oversz signing request (role=%d sz=%lu)", role, sz ));
      83           0 :     return 0;
      84           0 :   }
      85             : 
      86             :   /* Identify payload type */
      87             : 
      88           0 :   ulong payload_mask = fd_keyguard_payload_match( data, sz, sign_type );
      89           0 :   int   match_cnt    = fd_ulong_popcnt( payload_mask );
      90           0 :   if( FD_UNLIKELY( payload_mask==0UL ) ) {
      91           0 :     FD_LOG_WARNING(( "unrecognized payload type (role=%#x)", (uint)role ));
      92           0 :   }
      93             : 
      94           0 :   int is_ambiguous = match_cnt != 1;
      95             : 
      96             :  /* We know that gossip, gossip prune, and repair messages are
      97             :     ambiguous, so allow mismatches here. */
      98           0 :   int is_gossip_repair =
      99           0 :     0==( payload_mask &
     100           0 :         (~( FD_KEYGUARD_PAYLOAD_GOSSIP |
     101           0 :             FD_KEYGUARD_PAYLOAD_REPAIR |
     102           0 :             FD_KEYGUARD_PAYLOAD_PRUNE  ) ) );
     103             : 
     104           0 :   if( FD_UNLIKELY( is_ambiguous && !is_gossip_repair ) ) {
     105           0 :     FD_LOG_WARNING(( "ambiguous payload type (role=%#x mask=%#lx)", (uint)role, payload_mask ));
     106           0 :   }
     107             : 
     108             :   /* Authorize each role */
     109             : 
     110           0 :   switch( role ) {
     111             : 
     112           0 :   case FD_KEYGUARD_ROLE_VOTER:
     113           0 :     if( FD_UNLIKELY( payload_mask != FD_KEYGUARD_PAYLOAD_TXN ) ) {
     114           0 :       FD_LOG_WARNING(( "unauthorized payload type for voter (mask=%#lx)", payload_mask ));
     115           0 :       return 0;
     116           0 :     }
     117           0 :     return fd_keyguard_authorize_vote_txn( authority, data, sz, sign_type );
     118             : 
     119           0 :   case FD_KEYGUARD_ROLE_GOSSIP: {
     120           0 :     int ping_ok   = (!!( payload_mask & FD_KEYGUARD_PAYLOAD_PING )) &&
     121           0 :                     fd_keyguard_authorize_ping( authority, data, sz, sign_type );
     122           0 :     int prune_ok  = (!!( payload_mask & FD_KEYGUARD_PAYLOAD_PRUNE )) &&
     123           0 :                     fd_keyguard_authorize_gossip_prune( authority, data, sz, sign_type );
     124           0 :     int gossip_ok = (!!( payload_mask & FD_KEYGUARD_PAYLOAD_GOSSIP )) &&
     125           0 :                     fd_keyguard_authorize_gossip( authority, data, sz, sign_type );
     126           0 :     if( FD_UNLIKELY( !ping_ok && !prune_ok && !gossip_ok ) ) {
     127           0 :       FD_LOG_WARNING(( "unauthorized payload type for gossip (mask=%#lx)", payload_mask ));
     128           0 :       return 0;
     129           0 :     }
     130           0 :     return 1;
     131           0 :   }
     132             : 
     133           0 :   case FD_KEYGUARD_ROLE_REPAIR: {
     134           0 :     int ping_ok   = (!!( payload_mask & FD_KEYGUARD_PAYLOAD_PING )) &&
     135           0 :                     fd_keyguard_authorize_ping( authority, data, sz, sign_type );
     136           0 :     int repair_ok = (!!( payload_mask & FD_KEYGUARD_PAYLOAD_REPAIR )) &&
     137           0 :                     fd_keyguard_authorize_repair( authority, data, sz, sign_type );
     138           0 :     if( FD_UNLIKELY( !ping_ok && !repair_ok ) ) {
     139           0 :       FD_LOG_WARNING(( "unauthorized payload type for repair (mask=%#lx)", payload_mask ));
     140           0 :       return 0;
     141           0 :     }
     142           0 :     return 1;
     143           0 :   }
     144             : 
     145           0 :   case FD_KEYGUARD_ROLE_LEADER:
     146           0 :     if( FD_UNLIKELY( payload_mask != FD_KEYGUARD_PAYLOAD_SHRED ) ) {
     147           0 :       FD_LOG_WARNING(( "unauthorized payload type for leader (mask=%#lx)", payload_mask ));
     148           0 :       return 0;
     149           0 :     }
     150             :     /* no further restrictions on shred */
     151           0 :     return 1;
     152             : 
     153           0 :   case FD_KEYGUARD_ROLE_BUNDLE:
     154           0 :     if( FD_UNLIKELY( payload_mask != FD_KEYGUARD_PAYLOAD_BUNDLE ) ) {
     155           0 :       FD_LOG_WARNING(( "unauthorized payload type for bundle (mask=%#lx)", payload_mask ));
     156           0 :       return 0;
     157           0 :     }
     158             :     /* no further restrictions on bundle */
     159           0 :     return 1;
     160             : 
     161           0 :   default:
     162           0 :     FD_LOG_WARNING(( "unsupported role=%#x", (uint)role ));
     163           0 :     return 0;
     164           0 :   }
     165           0 : }

Generated by: LCOV version 1.14