21
21
#define CERT_HASH_STR_LEN 40
22
22
#define CERT_HASH_LEN 20
23
23
24
+ /**
25
+ * Split system cert path into exactly three segments like:
26
+ * "CurrentUser\My\a11f8a9b5df5b98ba3508fbca575d09570e0d2c6"
27
+ * -> ["CurrentUser", "My", "a11f8a9b5df5b98ba3508fbca575d09570e0d2c6"]
28
+ */
29
+ static int s_split_system_cert_path (const char * cert_path , struct aws_byte_cursor out_splits [3 ]) {
30
+
31
+ struct aws_byte_cursor cert_path_cursor = aws_byte_cursor_from_c_str (cert_path );
32
+
33
+ struct aws_byte_cursor segment ;
34
+ AWS_ZERO_STRUCT (segment );
35
+
36
+ for (size_t i = 0 ; i < 3 ; ++ i ) {
37
+ if (!aws_byte_cursor_next_split (& cert_path_cursor , '\\' , & segment )) {
38
+ AWS_LOGF_ERROR (
39
+ AWS_LS_IO_PKI , "static: invalid certificate path '%s'. Expected additional '\\' separator." , cert_path );
40
+ return aws_raise_error (AWS_ERROR_FILE_INVALID_PATH );
41
+ }
42
+
43
+ out_splits [i ] = segment ;
44
+ }
45
+
46
+ if (aws_byte_cursor_next_split (& cert_path_cursor , '\\' , & segment )) {
47
+ AWS_LOGF_ERROR (
48
+ AWS_LS_IO_PKI , "static: invalid certificate path '%s'. Too many '\\' separators found." , cert_path );
49
+ return aws_raise_error (AWS_ERROR_FILE_INVALID_PATH );
50
+ }
51
+
52
+ return AWS_OP_SUCCESS ;
53
+ }
54
+
24
55
int aws_load_cert_from_system_cert_store (const char * cert_path , HCERTSTORE * cert_store , PCCERT_CONTEXT * certs ) {
25
56
26
57
AWS_LOGF_INFO (AWS_LS_IO_PKI , "static: loading certificate at windows cert manager path '%s'." , cert_path );
27
- char * location_of_next_segment = strchr (cert_path , '\\' );
28
58
29
- if (! location_of_next_segment ) {
30
- AWS_LOGF_ERROR ( AWS_LS_IO_PKI , "static: invalid certificate path '%s'. Must use '\\' as separator." , cert_path );
31
- return aws_raise_error ( AWS_ERROR_FILE_INVALID_PATH ) ;
59
+ struct aws_byte_cursor segments [ 3 ];
60
+ if ( s_split_system_cert_path ( cert_path , segments )) {
61
+ return AWS_OP_ERR ;
32
62
}
63
+ const struct aws_byte_cursor store_location = segments [0 ];
64
+ const struct aws_byte_cursor store_path_cursor = segments [1 ];
65
+ const struct aws_byte_cursor cert_hash_cursor = segments [2 ];
33
66
34
- size_t store_name_len = location_of_next_segment - cert_path ;
35
67
DWORD store_val = 0 ;
36
-
37
- if (!strncmp (cert_path , "CurrentUser" , store_name_len )) {
68
+ if (aws_byte_cursor_eq_c_str_ignore_case (& store_location , "CurrentUser" )) {
38
69
store_val = CERT_SYSTEM_STORE_CURRENT_USER ;
39
- } else if (! strncmp ( cert_path , "LocalMachine" , store_name_len )) {
70
+ } else if (aws_byte_cursor_eq_c_str_ignore_case ( & store_location , "LocalMachine" )) {
40
71
store_val = CERT_SYSTEM_STORE_LOCAL_MACHINE ;
41
- } else if (! strncmp ( cert_path , "CurrentService" , store_name_len )) {
72
+ } else if (aws_byte_cursor_eq_c_str_ignore_case ( & store_location , "CurrentService" )) {
42
73
store_val = CERT_SYSTEM_STORE_CURRENT_SERVICE ;
43
- } else if (! strncmp ( cert_path , "Services" , store_name_len )) {
74
+ } else if (aws_byte_cursor_eq_c_str_ignore_case ( & store_location , "Services" )) {
44
75
store_val = CERT_SYSTEM_STORE_SERVICES ;
45
- } else if (! strncmp ( cert_path , "Users" , store_name_len )) {
76
+ } else if (aws_byte_cursor_eq_c_str_ignore_case ( & store_location , "Users" )) {
46
77
store_val = CERT_SYSTEM_STORE_USERS ;
47
- } else if (! strncmp ( cert_path , "CurrentUserGroupPolicy" , store_name_len )) {
78
+ } else if (aws_byte_cursor_eq_c_str_ignore_case ( & store_location , "CurrentUserGroupPolicy" )) {
48
79
store_val = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY ;
49
- } else if (! strncmp ( cert_path , "LocalMachineGroupPolicy" , store_name_len )) {
80
+ } else if (aws_byte_cursor_eq_c_str_ignore_case ( & store_location , "LocalMachineGroupPolicy" )) {
50
81
store_val = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY ;
51
- } else if (! strncmp ( cert_path , "LocalMachineEnterprise" , store_name_len )) {
82
+ } else if (aws_byte_cursor_eq_c_str_ignore_case ( & store_location , "LocalMachineEnterprise" )) {
52
83
store_val = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE ;
53
84
} else {
54
85
AWS_LOGF_ERROR (
55
86
AWS_LS_IO_PKI ,
56
- "static: invalid certificate path '%s'. System store location '%.*s ' not recognized."
87
+ "static: invalid certificate path '%s'. System store location '" PRInSTR " ' not recognized."
57
88
" Expected something like 'CurrentUser'." ,
58
89
cert_path ,
59
- (int )store_name_len ,
60
- cert_path );
90
+ AWS_BYTE_CURSOR_PRI (store_location ));
61
91
62
92
return aws_raise_error (AWS_ERROR_FILE_INVALID_PATH );
63
93
}
64
94
65
95
AWS_LOGF_DEBUG (AWS_LS_IO_PKI , "static: determined registry value for lookup as %d." , (int )store_val );
66
- location_of_next_segment += 1 ;
67
- char * store_path_start = location_of_next_segment ;
68
- location_of_next_segment = strchr (location_of_next_segment , '\\' );
69
-
70
- if (!location_of_next_segment ) {
71
- AWS_LOGF_ERROR (
72
- AWS_LS_IO_PKI , "static: invalid certificate path '%s'. Expected additional '\\' separator." , cert_path );
73
- return aws_raise_error (AWS_ERROR_FILE_INVALID_PATH );
74
- }
75
96
76
97
/* The store_val value has to be only the path segment related to the physical store. Looking
77
98
at the docs, 128 bytes should be plenty to store that segment.
78
99
https://docs.microsoft.com/en-us/windows/desktop/SecCrypto/system-store-locations */
79
100
char store_path [128 ] = {0 };
80
- if (location_of_next_segment - store_path_start >= sizeof (store_path )) {
101
+ if (store_path_cursor . len >= sizeof (store_path )) {
81
102
AWS_LOGF_ERROR (AWS_LS_IO_PKI , "static: invalid certificate path '%s'. Store name is too long." , cert_path );
82
103
return aws_raise_error (AWS_ERROR_FILE_INVALID_PATH );
83
104
}
84
- memcpy (store_path , store_path_start , location_of_next_segment - store_path_start );
105
+ memcpy (store_path , store_path_cursor . ptr , store_path_cursor . len );
85
106
86
- location_of_next_segment += 1 ;
87
- if (strlen (location_of_next_segment ) != CERT_HASH_STR_LEN ) {
107
+ if (cert_hash_cursor .len != CERT_HASH_STR_LEN ) {
88
108
AWS_LOGF_ERROR (
89
109
AWS_LS_IO_PKI ,
90
- "static: invalid certificate path '%s'. '%s ' should have been"
110
+ "static: invalid certificate path '%s'. '" PRInSTR " ' should have been"
91
111
" 40 bytes of hex encoded data" ,
92
112
cert_path ,
93
- location_of_next_segment );
113
+ AWS_BYTE_CURSOR_PRI ( cert_hash_cursor ) );
94
114
return aws_raise_error (AWS_ERROR_FILE_INVALID_PATH );
95
115
}
96
116
@@ -113,7 +133,7 @@ int aws_load_cert_from_system_cert_store(const char *cert_path, HCERTSTORE *cert
113
133
};
114
134
115
135
if (!CryptStringToBinaryA (
116
- location_of_next_segment ,
136
+ ( LPCSTR ) cert_hash_cursor . ptr , /* this is null-terminated, it's the last segment of c-str */
117
137
CERT_HASH_STR_LEN ,
118
138
CRYPT_STRING_HEX ,
119
139
cert_hash .pbData ,
@@ -122,9 +142,9 @@ int aws_load_cert_from_system_cert_store(const char *cert_path, HCERTSTORE *cert
122
142
NULL )) {
123
143
AWS_LOGF_ERROR (
124
144
AWS_LS_IO_PKI ,
125
- "static: invalid certificate path '%s'. '%s ' should have been a hex encoded string" ,
145
+ "static: invalid certificate path '%s'. '" PRInSTR " ' should have been a hex encoded string" ,
126
146
cert_path ,
127
- location_of_next_segment );
147
+ AWS_BYTE_CURSOR_PRI ( cert_hash_cursor ) );
128
148
aws_raise_error (AWS_ERROR_FILE_INVALID_PATH );
129
149
goto on_error ;
130
150
}
0 commit comments