Skip to content

Commit 92d8828

Browse files
committed
refactor: add decode_object
To remove repeated double-call (once to get length, once to decode).
1 parent 28c4d7a commit 92d8828

File tree

1 file changed

+63
-96
lines changed

1 file changed

+63
-96
lines changed

src/libmongoc/src/mongoc/mongoc-secure-channel.c

Lines changed: 63 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,56 @@ read_file_and_null_terminate (const char *filename, size_t *out_len)
149149
}
150150

151151

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+
152202
PCCERT_CONTEXT
153203
mongoc_secure_channel_setup_certificate_from_file (const char *filename)
154204
{
@@ -204,34 +254,9 @@ mongoc_secure_channel_setup_certificate_from_file (const char *filename)
204254
goto fail;
205255
}
206256

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) {
235260
goto fail;
236261
}
237262
} else if (NULL != (pem_private = strstr (pem, "-----BEGIN PRIVATE KEY-----"))) {
@@ -240,36 +265,9 @@ mongoc_secure_channel_setup_certificate_from_file (const char *filename)
240265
goto fail;
241266
}
242267

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) {
273271
goto fail;
274272
}
275273

@@ -280,44 +278,13 @@ mongoc_secure_channel_setup_certificate_from_file (const char *filename)
280278
goto fail;
281279
}
282280

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) {
321288
goto fail;
322289
}
323290
} else {

0 commit comments

Comments
 (0)