@@ -7,38 +7,31 @@ use newrelic_agent_control::opamp::remote_config::DEFAULT_AGENT_CONFIG_IDENTIFIE
77use newrelic_agent_control:: opamp:: remote_config:: signature:: {
88 ED25519 , SIGNATURE_CUSTOM_CAPABILITY , SIGNATURE_CUSTOM_MESSAGE_TYPE , SignatureFields ,
99} ;
10- use newrelic_agent_control:: opamp:: remote_config:: validators:: signature:: public_key_fingerprint;
1110use opamp_client:: opamp:: proto:: {
1211 AgentConfigFile , AgentConfigMap , AgentDescription , AgentRemoteConfig , AgentToServer ,
1312 ComponentHealth , CustomMessage , EffectiveConfig , RemoteConfigStatus , ServerToAgent ,
1413 ServerToAgentFlags ,
1514} ;
1615use opamp_client:: operation:: instance_uid:: InstanceUid ;
1716use prost:: Message ;
18- use rcgen:: { CertificateParams , KeyPair , PKCS_ED25519 , PublicKeyData } ;
1917use ring:: digest;
2018use ring:: rand:: SystemRandom ;
2119use ring:: signature:: { Ed25519KeyPair , KeyPair as _} ;
2220use serde_json:: json;
2321use std:: hash:: { DefaultHasher , Hash , Hasher } ;
24- use std:: path:: PathBuf ;
2522use std:: sync:: Mutex ;
2623use std:: { collections:: HashMap , net, sync:: Arc } ;
27- use tempfile:: TempDir ;
2824use tokio:: task:: JoinHandle ;
2925
3026const FAKE_SERVER_PATH : & str = "/opamp-fake-server" ;
3127const JWKS_SERVER_PATH : & str = "/jwks" ;
32- const CERT_FILE : & str = "server.crt " ;
28+ const JWKS_PUBLIC_KEY_ID : & str = "fakeKeyName/0 " ;
3329
3430/// Represents the state of the FakeServer.
3531struct ServerState {
3632 agent_state : HashMap < InstanceID , AgentState > ,
3733 // Key pair to sign remote configuration
3834 key_pair : Ed25519KeyPair ,
39- // Use the legacy system (instead of key_pair) to sign remote configuration
40- use_legacy_signatures : bool ,
41- legacy_key_pair : KeyPair , // TODO: cleanup when no longer used
4235}
4336
4437#[ derive( Default ) ]
@@ -52,12 +45,10 @@ struct AgentState {
5245}
5346
5447impl ServerState {
55- fn new ( cert_key_pair : KeyPair , use_legacy_signatures : bool ) -> Self {
48+ fn new ( ) -> Self {
5649 Self {
5750 agent_state : HashMap :: new ( ) ,
5851 key_pair : generate_key_pair ( ) ,
59- use_legacy_signatures,
60- legacy_key_pair : cert_key_pair,
6152 }
6253 }
6354}
@@ -87,7 +78,6 @@ pub struct FakeServer {
8778 state : Arc < Mutex < ServerState > > ,
8879 port : u16 ,
8980 path : String ,
90- cert_tmp_dir : TempDir ,
9181}
9282
9383impl FakeServer {
@@ -102,30 +92,11 @@ impl FakeServer {
10292
10393 /// Starts and returns new FakeServer in a random port.
10494 pub fn start_new ( ) -> Self {
105- Self :: start_new_with_legacy_signatures ( false )
106- }
107-
108- /// If `use_legacy_signatures` is set to true, the jwks endpoint is still available but
109- /// configs are signed using the legacy system.
110- pub fn start_new_with_legacy_signatures ( use_legacy_signatures : bool ) -> Self {
11195 // While binding to port 0, the kernel gives you a free ephemeral port.
11296 let listener = net:: TcpListener :: bind ( "0.0.0.0:0" ) . unwrap ( ) ;
11397 let port = listener. local_addr ( ) . unwrap ( ) . port ( ) ;
11498
115- // Legacy certificate-based key pair
116- let legacy_key_pair = KeyPair :: generate_for ( & PKCS_ED25519 ) . unwrap ( ) ;
117- let cert = CertificateParams :: new ( vec ! [ "localhost" . to_string( ) ] )
118- . unwrap ( )
119- . self_signed ( & legacy_key_pair)
120- . unwrap ( ) ;
121-
122- let tmp_dir = tempfile:: tempdir ( ) . unwrap ( ) ;
123- std:: fs:: write ( tmp_dir. path ( ) . join ( CERT_FILE ) , cert. pem ( ) ) . unwrap ( ) ;
124-
125- let state = Arc :: new ( Mutex :: new ( ServerState :: new (
126- legacy_key_pair,
127- use_legacy_signatures,
128- ) ) ) ;
99+ let state = Arc :: new ( Mutex :: new ( ServerState :: new ( ) ) ) ;
129100
130101 let handle = tokio_runtime ( ) . spawn ( Self :: run_http_server ( listener, state. clone ( ) ) ) ;
131102
@@ -134,7 +105,6 @@ impl FakeServer {
134105 state,
135106 port,
136107 path : FAKE_SERVER_PATH . to_string ( ) ,
137- cert_tmp_dir : tmp_dir,
138108 }
139109 }
140110
@@ -165,10 +135,6 @@ impl FakeServer {
165135 . remote_config = Some ( response. as_ref ( ) . into ( ) ) ;
166136 }
167137
168- pub fn cert_file_path ( & self ) -> PathBuf {
169- self . cert_tmp_dir . path ( ) . join ( CERT_FILE )
170- }
171-
172138 pub fn get_health_status ( & self , identifier : & InstanceID ) -> Option < ComponentHealth > {
173139 let state = self . state . lock ( ) . unwrap ( ) ;
174140 state
@@ -269,26 +235,7 @@ async fn opamp_handler(state: web::Data<Arc<Mutex<ServerState>>>, req: web::Byte
269235
270236 let _ = agent_state; // We need to get rid of the mutable reference before leveraging another immutable.
271237
272- let ( key_pair, key_id) = if server_state. use_legacy_signatures {
273- (
274- & Ed25519KeyPair :: from_pkcs8 ( & server_state. legacy_key_pair . serialize_der ( ) ) . unwrap ( ) ,
275- public_key_fingerprint ( & server_state. legacy_key_pair . subject_public_key_info ( ) ) ,
276- )
277- } else {
278- let public_key = server_state. key_pair . public_key ( ) . as_ref ( ) . to_vec ( ) ;
279- ( & server_state. key_pair , public_key_fingerprint ( & public_key) )
280- } ;
281-
282- let use_legacy_signature = server_state. use_legacy_signatures ;
283-
284- let server_to_agent = build_response (
285- identifier,
286- remote_config,
287- key_pair,
288- key_id,
289- flags,
290- use_legacy_signature,
291- ) ;
238+ let server_to_agent = build_response ( identifier, remote_config, & server_state. key_pair , flags) ;
292239 HttpResponse :: Ok ( ) . body ( server_to_agent)
293240}
294241
@@ -302,7 +249,7 @@ async fn jwks_handler(state: web::Data<Arc<Mutex<ServerState>>>, _req: web::Byte
302249 "kty" : "OKP" ,
303250 "alg" : null,
304251 "use" : "sig" ,
305- "kid" : public_key_fingerprint ( & public_key ) ,
252+ "kid" : JWKS_PUBLIC_KEY_ID ,
306253 "n" : null,
307254 "x" : enc_public_key,
308255 "y" : null,
@@ -317,9 +264,7 @@ fn build_response(
317264 instance_id : InstanceID ,
318265 agent_remote_config : Option < RemoteConfig > ,
319266 key_pair : & Ed25519KeyPair ,
320- key_id : String ,
321267 flags : u64 ,
322- use_legacy_signature : bool ,
323268) -> Vec < u8 > {
324269 let mut remote_config = None ;
325270 let mut custom_message = None ;
@@ -338,25 +283,20 @@ fn build_response(
338283 } ) ,
339284 } ) ;
340285
341- let msg = if use_legacy_signature {
342- config. raw_body
343- } else {
344- // Actual implementation from FC side signs the Base64 representation of the SHA256 digest
345- // of the message (i.e. the remote configs). Hence, to verify the signature, we need to
346- // compute the SHA256 digest of the message, then Base64 encode it, and finally verify
347- // the signature against that.
348- let digest = digest:: digest ( & digest:: SHA256 , config. raw_body . as_bytes ( ) ) ;
349- BASE64_STANDARD . encode ( digest)
350- } ;
351-
286+ // Actual implementation from FC side signs the Base64 representation of the SHA256 digest
287+ // of the message (i.e. the remote configs). Hence, to verify the signature, we need to
288+ // compute the SHA256 digest of the message, then Base64 encode it, and finally verify
289+ // the signature against that.
290+ let digest = digest:: digest ( & digest:: SHA256 , config. raw_body . as_bytes ( ) ) ;
291+ let msg = BASE64_STANDARD . encode ( digest) ;
352292 let signature = key_pair. sign ( msg. as_bytes ( ) ) ;
353293
354294 let custom_message_data = HashMap :: from ( [ (
355295 DEFAULT_AGENT_CONFIG_IDENTIFIER . to_string ( ) ,
356296 vec ! [ SignatureFields {
357297 signature: BASE64_STANDARD . encode( signature) ,
358298 signing_algorithm: ED25519 ,
359- key_id,
299+ key_id: JWKS_PUBLIC_KEY_ID . to_string ( ) ,
360300 } ] ,
361301 ) ] ) ;
362302
0 commit comments