/ tests / integration / test_security.rs
test_security.rs
  1  //! Integration tests for security features.
  2  //!
  3  //! Tests: checksum verification, signature verification, file permissions
  4  
  5  mod common;
  6  
  7  use common::assertions::*;
  8  use common::fixtures::*;
  9  use common::mocks::*;
 10  use common::TestEnv;
 11  use sha2::{Digest, Sha256};
 12  
 13  #[test]
 14  fn test_checksum_verification_success() {
 15      // Setup
 16      let env = TestEnv::new().expect("Failed to create test environment");
 17      let release_server = MockReleaseServer::new("https://secure.ac-dc.network".to_string());
 18  
 19      // Create binary content
 20      let binary_content = b"#!/bin/bash\necho 'adnet v1.0.0'";
 21  
 22      // Calculate correct checksum
 23      let mut hasher = Sha256::new();
 24      hasher.update(binary_content);
 25      let expected_checksum = format!("{:x}", hasher.finalize());
 26  
 27      // Add to release server
 28      release_server.add_file("/releases/adnet-v1.0.0.tar.gz", binary_content.to_vec());
 29      release_server.add_checksum("/releases/adnet-v1.0.0.tar.gz", &expected_checksum);
 30  
 31      // Download and verify
 32      let downloaded = release_server
 33          .get_file("/releases/adnet-v1.0.0.tar.gz")
 34          .expect("Failed to download");
 35      let checksum = release_server
 36          .get_checksum("/releases/adnet-v1.0.0.tar.gz")
 37          .expect("Failed to get checksum");
 38  
 39      // Verify checksum matches
 40      let mut hasher = Sha256::new();
 41      hasher.update(&downloaded);
 42      let actual_checksum = format!("{:x}", hasher.finalize());
 43  
 44      assert_eq!(
 45          actual_checksum, checksum,
 46          "Checksum verification should succeed"
 47      );
 48  
 49      // Install verified binary
 50      let binary_path = env.install_dir.join("adnet");
 51      std::fs::write(&binary_path, &downloaded).expect("Failed to write binary");
 52  
 53      assert_binary_exists(&binary_path);
 54  }
 55  
 56  #[test]
 57  fn test_checksum_mismatch_rejection() {
 58      // Setup
 59      let env = TestEnv::new().expect("Failed to create test environment");
 60      let release_server = MockReleaseServer::new("https://test.ac-dc.network".to_string());
 61  
 62      // Add binary with mismatched checksum
 63      let binary_content = b"#!/bin/bash\necho 'malicious'";
 64      release_server.add_file("/releases/adnet-v1.0.0.tar.gz", binary_content.to_vec());
 65      release_server.add_checksum(
 66          "/releases/adnet-v1.0.0.tar.gz",
 67          "incorrect_checksum_abc123",
 68      );
 69  
 70      // Download
 71      let downloaded = release_server
 72          .get_file("/releases/adnet-v1.0.0.tar.gz")
 73          .expect("Failed to download");
 74      let expected_checksum = release_server
 75          .get_checksum("/releases/adnet-v1.0.0.tar.gz")
 76          .expect("Failed to get checksum");
 77  
 78      // Calculate actual checksum
 79      let mut hasher = Sha256::new();
 80      hasher.update(&downloaded);
 81      let actual_checksum = format!("{:x}", hasher.finalize());
 82  
 83      // Verify mismatch detected
 84      assert_ne!(
 85          actual_checksum, expected_checksum,
 86          "Checksum mismatch should be detected"
 87      );
 88  
 89      // Binary should NOT be installed
 90      let binary_path = env.install_dir.join("adnet");
 91      assert!(
 92          !binary_path.exists(),
 93          "Binary with bad checksum should not be installed"
 94      );
 95  }
 96  
 97  #[test]
 98  fn test_signature_verification() {
 99      // Setup
100      let env = TestEnv::new().expect("Failed to create test environment");
101  
102      // Create a mock signature file
103      let binary_path = env.install_dir.join("adnet");
104      let binary_content = b"#!/bin/bash\necho 'adnet'";
105      std::fs::write(&binary_path, binary_content).expect("Failed to write binary");
106  
107      let signature_path = env.install_dir.join("adnet.sig");
108      let mock_signature = b"MOCK_SIGNATURE_DATA_abc123def456";
109      std::fs::write(&signature_path, mock_signature).expect("Failed to write signature");
110  
111      // Verify both files exist
112      assert!(binary_path.exists());
113      assert!(signature_path.exists());
114  
115      // In real implementation, would verify signature using public key
116      // For test, we just verify the signature file is readable
117      let sig_content = std::fs::read(&signature_path).expect("Failed to read signature");
118      assert_eq!(sig_content, mock_signature);
119  
120      // Simulate signature verification success
121      let signature_valid = sig_content.len() > 0; // Simplified check
122      assert!(signature_valid, "Signature should be valid");
123  }
124  
125  #[test]
126  fn test_file_permissions_enforcement() {
127      // Setup
128      let env = TestEnv::new().expect("Failed to create test environment");
129  
130      // Create binary with correct permissions
131      let binary_path = env
132          .create_binary("adnet", b"#!/bin/bash\necho 'test'")
133          .expect("Failed to create binary");
134  
135      #[cfg(unix)]
136      {
137          use std::os::unix::fs::PermissionsExt;
138  
139          // Verify binary is executable (0755)
140          let metadata = std::fs::metadata(&binary_path).unwrap();
141          let permissions = metadata.permissions();
142          let mode = permissions.mode();
143  
144          assert_eq!(mode & 0o777, 0o755, "Binary should be executable (0755)");
145  
146          // Create config file with restricted permissions (0600)
147          let config_path = env.config_dir.join("secrets.toml");
148          std::fs::write(&config_path, "api_key = \"secret123\"").expect("Failed to write config");
149  
150          let mut perms = std::fs::metadata(&config_path).unwrap().permissions();
151          perms.set_mode(0o600);
152          std::fs::set_permissions(&config_path, perms).expect("Failed to set permissions");
153  
154          // Verify restricted permissions
155          let metadata = std::fs::metadata(&config_path).unwrap();
156          let mode = metadata.permissions().mode();
157          assert_eq!(mode & 0o777, 0o600, "Config should be restricted (0600)");
158  
159          // Create key file with strict permissions (0600)
160          let key_path = env.config_dir.join("node.key");
161          create_sample_key_file(&key_path).expect("Failed to create key");
162  
163          let metadata = std::fs::metadata(&key_path).unwrap();
164          let mode = metadata.permissions().mode();
165          assert_eq!(mode & 0o777, 0o600, "Key should be restricted (0600)");
166      }
167  
168      #[cfg(not(unix))]
169      {
170          // Windows doesn't use Unix permissions
171          // Just verify files exist
172          assert!(binary_path.exists());
173      }
174  }