LCOV - code coverage report
Current view: top level - disco/keyguard - fd_keyguard_authorize.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 138 0.0 %
Date: 2025-08-05 05:04:49 Functions: 0 8 0.0 %

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

Generated by: LCOV version 1.14