@@ -149,6 +149,56 @@ read_file_and_null_terminate (const char *filename, size_t *out_len)
149
149
}
150
150
151
151
152
+ // `decode_object` decodes a cryptographic object from a blob.
153
+ // Returns NULL on error.
154
+ static LPBYTE
155
+ decode_object (const char * structType ,
156
+ const LPBYTE data ,
157
+ DWORD data_len ,
158
+ DWORD * out_len ,
159
+ const char * descriptor ,
160
+ const char * filename )
161
+ {
162
+ // Get needed output length:
163
+ if (!CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , /* dwCertEncodingType */
164
+ structType , /* lpszStructType */
165
+ data , /* pbEncoded */
166
+ data_len , /* cbEncoded */
167
+ 0 , /* dwFlags */
168
+ NULL , /* pDecodePara */
169
+ NULL , /* pvStructInfo */
170
+ out_len /* pcbStructInfo */
171
+ )) {
172
+ char * msg = mongoc_winerr_to_string (GetLastError ());
173
+ MONGOC_ERROR ("Failed to decode %s from '%s': %s" , descriptor , filename , msg );
174
+ bson_free (msg );
175
+ return NULL ;
176
+ }
177
+
178
+ if (* out_len == 0 ) {
179
+ return NULL ;
180
+ }
181
+ LPBYTE out = (LPBYTE ) bson_malloc (* out_len );
182
+
183
+ if (!CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , /* dwCertEncodingType */
184
+ structType , /* lpszStructType */
185
+ data , /* pbEncoded */
186
+ data_len , /* cbEncoded */
187
+ 0 , /* dwFlags */
188
+ NULL , /* pDecodePara */
189
+ out , /* pvStructInfo */
190
+ out_len /* pcbStructInfo */
191
+ )) {
192
+ char * msg = mongoc_winerr_to_string (GetLastError ());
193
+ MONGOC_ERROR ("Failed to decode %s from '%s': %s" , descriptor , filename , msg );
194
+ bson_free (msg );
195
+ bson_free (out );
196
+ return NULL ;
197
+ }
198
+
199
+ return out ;
200
+ }
201
+
152
202
PCCERT_CONTEXT
153
203
mongoc_secure_channel_setup_certificate_from_file (const char * filename )
154
204
{
@@ -204,34 +254,9 @@ mongoc_secure_channel_setup_certificate_from_file (const char *filename)
204
254
goto fail ;
205
255
}
206
256
207
- success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , /* dwCertEncodingType */
208
- PKCS_RSA_PRIVATE_KEY , /* lpszStructType */
209
- encoded_private , /* pbEncoded */
210
- encoded_private_len , /* cbEncoded */
211
- 0 , /* dwFlags */
212
- NULL , /* pDecodePara */
213
- NULL , /* pvStructInfo */
214
- & blob_private_rsa_len ); /* pcbStructInfo */
215
- if (!success ) {
216
- char * msg = mongoc_winerr_to_string (GetLastError ());
217
- MONGOC_ERROR ("Failed to parse private key. %s" , msg );
218
- bson_free (msg );
219
- goto fail ;
220
- }
221
-
222
- blob_private_rsa = (LPBYTE ) bson_malloc0 (blob_private_rsa_len );
223
- success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
224
- PKCS_RSA_PRIVATE_KEY ,
225
- encoded_private ,
226
- encoded_private_len ,
227
- 0 ,
228
- NULL ,
229
- blob_private_rsa ,
230
- & blob_private_rsa_len );
231
- if (!success ) {
232
- char * msg = mongoc_winerr_to_string (GetLastError ());
233
- MONGOC_ERROR ("Failed to parse private key: %s" , msg );
234
- bson_free (msg );
257
+ blob_private_rsa = decode_object (
258
+ PKCS_RSA_PRIVATE_KEY , encoded_private , encoded_private_len , & blob_private_rsa_len , "private key" , filename );
259
+ if (NULL == blob_private_rsa ) {
235
260
goto fail ;
236
261
}
237
262
} else if (NULL != (pem_private = strstr (pem , "-----BEGIN PRIVATE KEY-----" ))) {
@@ -240,36 +265,9 @@ mongoc_secure_channel_setup_certificate_from_file (const char *filename)
240
265
goto fail ;
241
266
}
242
267
243
- // Call to get necessary output length:
244
- success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , /* dwCertEncodingType */
245
- PKCS_PRIVATE_KEY_INFO , /* lpszStructType */
246
- encrypted_private , /* pbEncoded */
247
- encrypted_private_len , /* cbEncoded */
248
- 0 , /* dwFlags */
249
- NULL , /* pDecodePara */
250
- NULL , /* pvStructInfo */
251
- & blob_private_len ); /* pcbStructInfo */
252
- if (!success ) {
253
- char * msg = mongoc_winerr_to_string (GetLastError ());
254
- MONGOC_ERROR ("Failed to parse private key: %s" , msg );
255
- bson_free (msg );
256
- goto fail ;
257
- }
258
-
259
- blob_private = (LPBYTE ) bson_malloc0 (blob_private_len );
260
- // Call again to decode:
261
- success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
262
- PKCS_PRIVATE_KEY_INFO ,
263
- encrypted_private ,
264
- encrypted_private_len ,
265
- 0 ,
266
- NULL ,
267
- blob_private ,
268
- & blob_private_len );
269
- if (!success ) {
270
- char * msg = mongoc_winerr_to_string (GetLastError ());
271
- MONGOC_ERROR ("Failed to parse private key: %s" , msg );
272
- bson_free (msg );
268
+ blob_private = decode_object (
269
+ PKCS_PRIVATE_KEY_INFO , encoded_private , encoded_private_len , & blob_private_rsa_len , "private key" , filename );
270
+ if (!blob_private ) {
273
271
goto fail ;
274
272
}
275
273
@@ -280,44 +278,13 @@ mongoc_secure_channel_setup_certificate_from_file (const char *filename)
280
278
goto fail ;
281
279
}
282
280
283
- // Call to get necessary output length:
284
- success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , /* dwCertEncodingType */
285
- PKCS_RSA_PRIVATE_KEY , /* lpszStructType */
286
- privateKeyInfo -> PrivateKey .pbData , /* pbEncoded */
287
- privateKeyInfo -> PrivateKey .cbData , /* cbEncoded */
288
- 0 , /* dwFlags */
289
- NULL , /* pDecodePara */
290
- NULL , /* pvStructInfo */
291
- & blob_private_rsa_len ); /* pcbStructInfo */
292
- if (!success ) {
293
- LPTSTR msg = NULL ;
294
- FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY ,
295
- NULL ,
296
- GetLastError (),
297
- LANG_NEUTRAL ,
298
- (LPTSTR ) & msg ,
299
- 0 ,
300
- NULL );
301
- char * msg = mongoc_winerr_to_string (GetLastError ());
302
- MONGOC_ERROR ("Failed to parse private key: %s" , msg );
303
- bson_free (msg );
304
- goto fail ;
305
- }
306
-
307
- blob_private_rsa = (LPBYTE ) bson_malloc0 (blob_private_rsa_len );
308
- // Call again to decode:
309
- success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
310
- PKCS_RSA_PRIVATE_KEY ,
311
- privateKeyInfo -> PrivateKey .pbData , /* pbEncoded */
312
- privateKeyInfo -> PrivateKey .cbData , /* cbEncoded */
313
- 0 ,
314
- NULL ,
315
- blob_private_rsa ,
316
- & blob_private_rsa_len );
317
- if (!success ) {
318
- char * msg = mongoc_winerr_to_string (GetLastError ());
319
- MONGOC_ERROR ("Failed to parse private key: %s" , msg );
320
- bson_free (msg );
281
+ blob_private_rsa = decode_object (PKCS_RSA_PRIVATE_KEY ,
282
+ privateKeyInfo -> PrivateKey .pbData ,
283
+ privateKeyInfo -> PrivateKey .cbData ,
284
+ & blob_private_rsa_len ,
285
+ "private key" ,
286
+ filename );
287
+ if (!blob_private_rsa ) {
321
288
goto fail ;
322
289
}
323
290
} else {
0 commit comments