github.com/google/osv-scalibr@v0.4.1/detector/weakcredentials/winlocal/samreg/domainf_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package samreg 16 17 import ( 18 "slices" 19 "strings" 20 "testing" 21 ) 22 23 func TestDomainFDeriveSyskey(t *testing.T) { 24 tests := []struct { 25 name string 26 syskey []byte 27 buffer []byte 28 want []byte 29 wantErr bool 30 wantErrText string 31 }{ 32 { 33 name: "derivation_RC4_succeeds", 34 syskey: []byte("\x88\x93\xae\x93\x45\x13\xbd\xdd\x25\x47\x35\x16\x3e\x9d\x33\x00"), 35 buffer: []byte("\x02\x00\x01\x00\x00\x00\x00\x00\x40\x15\x3b\x97\x46\x9f\xce\x01\x26\x00\x00\x00\x00\x00\x00\x00\x00\x80\xa6\x0a\xff\xde\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\xcc\x1d\xcf\xfb\xff\xff\xff\x00\xcc\x1d\xcf\xfb\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x03\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x38\x00\x00\x00\x23\x7e\xe9\x12\xa7\x34\xbf\x93\x18\x6e\xaa\xc1\x83\x07\x59\xa1\xd6\x96\xa6\x99\x6b\xa9\x41\x61\x44\x92\xb0\xfb\xd0\x0a\xe9\xa6\x37\xd6\x7c\xc6\x99\x2b\xc7\x12\xfe\x22\xa0\x17\x71\xce\xd3\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x38\x00\x00\x00\x3d\xfe\xe0\xd7\x20\xeb\x39\xc1\x44\x1c\x8d\x05\x29\xd6\x83\x47\x92\xa2\x29\x38\xfc\x9e\xa7\x29\xa9\x36\x7d\x4a\xfc\x6c\xe1\xb3\xd3\xac\xd4\xac\xe2\x5b\xab\xf9\xf8\x3f\x09\xe1\x91\x1a\x7d\xda\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00"), 36 want: []byte("\x3d\x21\x2c\xe8\xa2\xda\x83\x43\xbd\xad\x1e\xf2\xcf\xb6\xb3\x1c"), 37 }, 38 { 39 name: "derivation_AES_succeeds", 40 syskey: []byte("\x95\x60\xbf\x6a\x47\xe0\xc9\x02\xb0\x82\x45\xf1\x96\xd5\x4e\x4f"), 41 buffer: []byte("\x03\x00\x01\x00\x00\x00\x00\x00\x7d\xdc\xe4\xd7\xae\x0a\xdb\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\xa6\x0a\xff\xde\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x44\x5f\x9a\xfe\xff\xff\xff\x00\x44\x5f\x9a\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xea\x03\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x70\x00\x00\x00\x30\x00\x00\x00\x20\x00\x00\x00\x69\xcc\x39\x99\xf8\xc2\x32\xee\x75\x6e\xfe\x19\xe5\x52\xfd\x7f\xdf\x24\xbb\x41\xd5\x88\x39\x31\x28\x60\x6e\x96\x0f\x0d\x9c\xc1\x86\x40\xd1\x41\x5b\x0a\x0b\x74\x36\xae\xcd\xcf\xb9\x64\xe1\x1d\xbb\x2c\x3a\x60\xf9\xab\x0e\x36\x02\xe6\x29\x24\x54\xed\xfa\x0e\xf3\xbe\x13\xbd\x24\x0a\x9c\x96\xca\xeb\xcc\x6c\x18\x19\x3e\x57\xb8\x51\x80\x81\x2a\x13\xe3\x1c\x76\x11\xd2\x47\x43\xaa\x10\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x70\x00\x00\x00\x30\x00\x00\x00\x20\x00\x00\x00\x17\xf1\xdf\x69\x49\x14\xce\x2b\xae\xa0\xf6\x6b\x79\x2f\xb3\x90\x9d\x08\x11\xbe\x24\xed\x58\x2a\x18\x60\xb3\x51\x63\x73\xd2\x3d\x88\x7c\xd5\x11\x17\x2c\xdc\x80\xa3\x32\x14\xd3\x4a\x08\xf5\x91\x5e\x47\xc2\xb4\x8f\x09\x4a\x7b\xd6\x37\x1b\xa9\xd1\x9a\x77\x05\xb0\xb7\x4f\xe0\xa8\xeb\x5b\xb6\x82\xfb\x00\x44\xd1\x13\xf6\x31\x57\xf2\x2f\xb8\x61\x67\x60\x4e\x63\x6a\xed\x83\x0c\x72\x55\x69\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00"), 42 want: []byte("\xfc\xde\xe8\x3a\xc6\xc1\x4b\x28\xf5\x26\x50\x1f\xc6\xe8\xbb\xc3"), 43 }, 44 { 45 name: "domainF_too_short_RC4_returns_error", 46 buffer: []byte("A"), 47 wantErr: true, 48 wantErrText: errDomainFTooShort.Error(), 49 }, 50 { 51 name: "domainF_too_short_AES_returns_error", 52 buffer: []byte(strings.Repeat("A", fDomStructKeyOffset) + "\x02" + strings.Repeat("A", 32)), 53 wantErr: true, 54 wantErrText: errDomainFTooShort.Error(), 55 }, 56 { 57 name: "invalid_RC4_checksum_returns_error", 58 syskey: []byte("\x88\x93\xae\x93\x45\x13\xbd\xdd\x25\x47\x34\x16\x3e\x9d\x33\x00"), 59 buffer: []byte("\x02\x00\x01\x00\x00\x00\x00\x00\x40\x15\x3b\x97\x46\x9f\xce\x01\x26\x00\x00\x00\x00\x00\x00\x00\x00\x80\xa6\x0a\xff\xde\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\xcc\x1d\xcf\xfb\xff\xff\xff\x00\xcc\x1d\xcf\xfb\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x03\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x38\x00\x00\x00\x23\x7e\xe9\x12\xa7\x34\xbf\x93\x18\x6e\xaa\xc1\x83\x07\x59\xa1\xd6\x96\xa6\x99\x6b\xa9\x41\x61\x44\x92\xb0\xfb\xd0\x0a\xe9\xa6\x37\xd6\x7c\xc6\x99\x2b\xc7\x12\xfe\x22\xa0\x17\x71\xce\xd3\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x38\x00\x00\x00\x3d\xfe\xe0\xd7\x20\xeb\x39\xc1\x44\x1c\x8d\x05\x29\xd6\x83\x47\x92\xa2\x29\x38\xfc\x9e\xa7\x29\xa9\x36\x7d\x4a\xfc\x6c\xe1\xb3\xd3\xac\xd4\xac\xe2\x5b\xab\xf9\xf8\x3f\x09\xe1\x91\x1a\x7d\xda\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00"), 60 wantErr: true, 61 wantErrText: errInvalidChecksum.Error(), 62 }, 63 { 64 name: "invalid_revision_returns_error", 65 buffer: []byte(strings.Repeat("A", fDomStructKeyOffset) + "\xFF"), 66 wantErr: true, 67 wantErrText: errInvalidRevision.Error(), 68 }, 69 { 70 name: "decode_syskey_RC4_failure_returns_error", 71 buffer: []byte(strings.Repeat("A", fDomStructKeyOffset) + "\x01"), 72 wantErr: true, 73 wantErrText: "unexpected EOF", 74 }, 75 { 76 name: "decode_syskey_AES_failure_returns_error", 77 buffer: []byte(strings.Repeat("A", fDomStructKeyOffset) + "\x02"), 78 wantErr: true, 79 wantErrText: "unexpected EOF", 80 }, 81 { 82 name: "missing_syskey_AES_returns_error", 83 syskey: []byte(""), 84 buffer: []byte(strings.Repeat("\x00", fDomStructKeyOffset) + "\x02" + strings.Repeat("\x00", 0xCC)), 85 wantErr: true, 86 wantErrText: "crypto/aes: invalid key size 0", 87 }, 88 } 89 90 for _, tc := range tests { 91 t.Run(tc.name, func(t *testing.T) { 92 got, gotErr := newDomainF(tc.buffer).DeriveSyskey(tc.syskey) 93 if (gotErr != nil) != tc.wantErr { 94 t.Errorf("DeriveSyskey(...): unexpected error: %v", gotErr) 95 } 96 97 if tc.wantErr { 98 if !strings.Contains(gotErr.Error(), tc.wantErrText) { 99 t.Errorf("DeriveSyskey(...): unexpected error, got: %v, want: %v", gotErr, tc.wantErrText) 100 } 101 102 return 103 } 104 105 if !slices.Equal(got, tc.want) { 106 t.Errorf("DeriveSyskey(...): got %x, want %x", got, tc.want) 107 } 108 }) 109 } 110 }