LCOV - code coverage report
Current view: top level - disco/keyguard - fd_keyguard_authorize.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 128 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 7 0.0 %

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

Generated by: LCOV version 1.14