VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/crypto/store.cpp@ 94157

Last change on this file since 94157 was 94157, checked in by vboxsync, 3 years ago

Runtime: Windows build fixes and updated .def file in preparation for openssl-3.0.1 switch, bugref:10128

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.0 KB
Line 
1/* $Id: store.cpp 94157 2022-03-10 15:11:22Z vboxsync $ */
2/** @file
3 * IPRT - Cryptographic (Certificate) Store.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/crypto/store.h>
33
34#include <iprt/asm.h>
35#include <iprt/err.h>
36#include <iprt/mem.h>
37#include <iprt/string.h>
38
39#include <iprt/crypto/pkcs7.h>
40#include <iprt/crypto/x509.h>
41
42#ifdef IPRT_WITH_OPENSSL
43# include "internal/openssl-pre.h"
44# include <openssl/x509.h>
45# include "internal/openssl-post.h"
46#endif
47
48#include "store-internal.h"
49
50
51/*********************************************************************************************************************************
52* Structures and Typedefs *
53*********************************************************************************************************************************/
54/**
55 * Internal representation of a (certificate,++) store.
56 */
57typedef struct RTCRSTOREINT
58{
59 /** Magic number (RTCRSTOREINT_MAGIC). */
60 uint32_t u32Magic;
61 /** Reference counter. */
62 uint32_t volatile cRefs;
63 /** Pointer to the store provider. */
64 PCRTCRSTOREPROVIDER pProvider;
65 /** Provider specific data. */
66 void *pvProvider;
67} RTCRSTOREINT;
68/** Pointer to the internal representation of a store. */
69typedef RTCRSTOREINT *PRTCRSTOREINT;
70
71/** Magic value for RTCRSTOREINT::u32Magic (Alfred Dillwyn "Dilly" Knox). */
72#define RTCRSTOREINT_MAGIC UINT32_C(0x18840723)
73/** Dead magic value for RTCRSTOREINT::u32Magic. */
74#define RTCRSTOREINT_MAGIC_DEAD UINT32_C(0x19430227)
75
76
77
78/**
79 * Internal method a store provider uses to create a store handle.
80 *
81 * @returns IPRT status code
82 * @param pProvider Pointer to the store provider callback table.
83 * @param pvProvider Pointer to the provider specific instance data.
84 * @param phStore Where to return the store handle.
85 */
86DECLHIDDEN(int) rtCrStoreCreate(PCRTCRSTOREPROVIDER pProvider, void *pvProvider, PRTCRSTORE phStore)
87{
88 PRTCRSTOREINT pThis = (PRTCRSTOREINT)RTMemAlloc(sizeof(*pThis));
89 if (pThis)
90 {
91 pThis->pvProvider = pvProvider;
92 pThis->pProvider = pProvider;
93 pThis->cRefs = 1;
94 pThis->u32Magic = RTCRSTOREINT_MAGIC;
95 *phStore = pThis;
96 return VINF_SUCCESS;
97 }
98 return VERR_NO_MEMORY;
99}
100
101
102/**
103 * For the parent forwarding of the in-memory store.
104 */
105DECLHIDDEN(PCRTCRSTOREPROVIDER) rtCrStoreGetProvider(RTCRSTORE hStore, void **ppvProvider)
106{
107 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
108 AssertPtrReturn(pThis, NULL);
109 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, NULL);
110 *ppvProvider = pThis->pvProvider;
111 return pThis->pProvider;
112}
113
114
115RTDECL(uint32_t) RTCrStoreRetain(RTCRSTORE hStore)
116{
117 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
118 AssertPtrReturn(pThis, UINT32_MAX);
119 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, UINT32_MAX);
120
121 uint32_t cRet = ASMAtomicIncU32(&pThis->cRefs);
122 Assert(cRet < 8192);
123 return cRet;
124}
125
126
127RTDECL(uint32_t) RTCrStoreRelease(RTCRSTORE hStore)
128{
129 if (hStore == NIL_RTCRSTORE)
130 return 0;
131
132 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
133 AssertPtrReturn(pThis, UINT32_MAX);
134 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, UINT32_MAX);
135
136 uint32_t cStore = ASMAtomicDecU32(&pThis->cRefs);
137 if (!cStore)
138 {
139 ASMAtomicWriteU32(&pThis->u32Magic, RTCRSTOREINT_MAGIC_DEAD);
140 pThis->pProvider->pfnDestroyStore(pThis->pvProvider);
141 RTMemFree(pThis);
142 }
143 return cStore;
144}
145
146
147RTDECL(PCRTCRCERTCTX) RTCrStoreCertByIssuerAndSerialNo(RTCRSTORE hStore, PCRTCRX509NAME pIssuer, PCRTASN1INTEGER pSerialNo)
148{
149 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
150 AssertPtrReturn(pThis, NULL);
151 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, NULL);
152 AssertPtrReturn(pIssuer, NULL);
153
154 int rc;
155 RTCRSTORECERTSEARCH Search;
156 if (pThis->pProvider->pfnCertFindByIssuerAndSerialNo)
157 rc = pThis->pProvider->pfnCertFindByIssuerAndSerialNo(pThis->pvProvider, pIssuer, pSerialNo, &Search);
158 else
159 rc = pThis->pProvider->pfnCertFindAll(pThis->pvProvider, &Search);
160
161 PCRTCRCERTCTX pCertCtx = NULL;
162 if (RT_SUCCESS(rc))
163 {
164 for (;;)
165 {
166 pCertCtx = pThis->pProvider->pfnCertSearchNext(pThis->pvProvider, &Search);
167 if (!pCertCtx)
168 break;
169
170 if ( pCertCtx->pCert
171 && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCertCtx->pCert, pIssuer, pSerialNo))
172 break;
173 RTCrCertCtxRelease(pCertCtx);
174 }
175
176 pThis->pProvider->pfnCertSearchDestroy(pThis->pvProvider, &Search);
177 }
178 else
179 AssertMsg(rc == VERR_NOT_FOUND, ("%Rrc\n", rc));
180 return pCertCtx;
181}
182
183
184RTDECL(int) RTCrStoreCertAddEncoded(RTCRSTORE hStore, uint32_t fFlags, void const *pvSrc, size_t cbSrc, PRTERRINFO pErrInfo)
185{
186 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
187 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
188 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
189 AssertPtrReturn(pvSrc, VERR_INVALID_POINTER);
190 AssertReturn(cbSrc > 16 && cbSrc < _1M, VERR_OUT_OF_RANGE);
191 AssertReturn(!(fFlags & ~(RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ENC_MASK)), VERR_INVALID_FLAGS);
192 AssertMsgReturn( (fFlags & RTCRCERTCTX_F_ENC_MASK) == RTCRCERTCTX_F_ENC_X509_DER
193 || (fFlags & RTCRCERTCTX_F_ENC_MASK) == RTCRCERTCTX_F_ENC_TAF_DER
194 , ("Only X.509 and TAF DER supported: %#x\n", fFlags), VERR_INVALID_FLAGS);
195
196 int rc;
197 if (pThis->pProvider->pfnCertAddEncoded)
198 rc = pThis->pProvider->pfnCertAddEncoded(pThis->pvProvider, fFlags, (uint8_t const *)pvSrc, (uint32_t)cbSrc, pErrInfo);
199 else
200 rc = VERR_WRITE_PROTECT;
201
202 return rc;
203}
204
205
206RTDECL(int) RTCrStoreCertAddX509(RTCRSTORE hStore, uint32_t fFlags, PRTCRX509CERTIFICATE pCertificate, PRTERRINFO pErrInfo)
207{
208 /*
209 * Validate.
210 */
211 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
212 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
213 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
214
215 AssertPtrReturn(pCertificate, VERR_INVALID_POINTER);
216 AssertReturn(RTCrX509Certificate_IsPresent(pCertificate), VERR_INVALID_PARAMETER);
217 int rc = RTCrX509Certificate_CheckSanity(pCertificate, 0, pErrInfo, "Cert");
218 AssertRCReturn(rc, rc);
219
220 AssertReturn(!(fFlags & ~(RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ENC_MASK)), VERR_INVALID_FLAGS);
221 AssertCompile(RTCRCERTCTX_F_ENC_X509_DER == 0);
222 AssertMsgReturn((fFlags & RTCRCERTCTX_F_ENC_MASK) == RTCRCERTCTX_F_ENC_X509_DER,
223 ("Invalid encoding: %#x\n", fFlags), VERR_INVALID_FLAGS);
224
225 /*
226 * Encode and add it using pfnCertAddEncoded.
227 */
228 if (pThis->pProvider->pfnCertAddEncoded)
229 {
230 PRTASN1CORE pCore = RTCrX509Certificate_GetAsn1Core(pCertificate);
231 uint32_t cbEncoded = 0;
232 rc = RTAsn1EncodePrepare(pCore, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
233 if (RT_SUCCESS(rc))
234 {
235 uint8_t * const pbEncoded = (uint8_t *)RTMemTmpAllocZ(cbEncoded);
236 if (pbEncoded)
237 {
238 rc = RTAsn1EncodeToBuffer(pCore, RTASN1ENCODE_F_DER, pbEncoded, cbEncoded, pErrInfo);
239 if (RT_SUCCESS(rc))
240 rc = pThis->pProvider->pfnCertAddEncoded(pThis->pvProvider, fFlags, pbEncoded, cbEncoded, pErrInfo);
241 RTMemTmpFree(pbEncoded);
242 }
243 else
244 rc = VERR_NO_TMP_MEMORY;
245 }
246 }
247 else
248 rc = VERR_WRITE_PROTECT;
249
250 return rc;
251}
252
253
254RTDECL(int) RTCrStoreCertAddPkcs7(RTCRSTORE hStore, uint32_t fFlags, PRTCRPKCS7CERT pCertificate, PRTERRINFO pErrInfo)
255{
256 AssertPtrReturn(pCertificate, VERR_INVALID_POINTER);
257 AssertReturn(RTCrPkcs7Cert_IsPresent(pCertificate), VERR_INVALID_PARAMETER);
258 switch (pCertificate->enmChoice)
259 {
260 case RTCRPKCS7CERTCHOICE_X509:
261 return RTCrStoreCertAddX509(hStore, fFlags, pCertificate->u.pX509Cert, pErrInfo);
262
263 case RTCRPKCS7CERTCHOICE_EXTENDED_PKCS6:
264 return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement EXTENDED_PKCS6");
265 case RTCRPKCS7CERTCHOICE_AC_V1:
266 return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement AC_V1");
267 case RTCRPKCS7CERTCHOICE_AC_V2:
268 return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement AC_V2");
269 case RTCRPKCS7CERTCHOICE_OTHER:
270 return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement OTHER");
271 case RTCRPKCS7CERTCHOICE_END:
272 case RTCRPKCS7CERTCHOICE_INVALID:
273 case RTCRPKCS7CERTCHOICE_32BIT_HACK:
274 break;
275 /* no default */
276 }
277 return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "Invalid RTCRPKCS7CERT enmChoice value: %d", pCertificate->enmChoice);
278}
279
280
281/*
282 * Searching.
283 * Searching.
284 * Searching.
285 */
286
287RTDECL(int) RTCrStoreCertFindAll(RTCRSTORE hStore, PRTCRSTORECERTSEARCH pSearch)
288{
289 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
290 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
291 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
292 AssertPtrReturn(pSearch, VERR_INVALID_POINTER);
293
294 return pThis->pProvider->pfnCertFindAll(pThis->pvProvider, pSearch);
295}
296
297
298/** Indicator for RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280 searches
299 * implemented by this front-end code. */
300#define RTCRSTORECERTSEARCH_BY_SUBECT_OR_ALT_SUBJECT_BY_RFC5280 UINT32_C(0x5be9145d)
301
302RTDECL(int) RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(RTCRSTORE hStore, PCRTCRX509NAME pSubject,
303 PRTCRSTORECERTSEARCH pSearch)
304{
305 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
306 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
307 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
308 AssertPtrReturn(pSearch, VERR_INVALID_POINTER);
309
310 int rc = pThis->pProvider->pfnCertFindAll(pThis->pvProvider, pSearch);
311 if (RT_SUCCESS(rc))
312 {
313 pSearch->auOpaque[2] = RTCRSTORECERTSEARCH_BY_SUBECT_OR_ALT_SUBJECT_BY_RFC5280;
314 pSearch->auOpaque[3] = (uintptr_t)pSubject;
315 }
316 return rc;
317}
318
319
320RTDECL(PCRTCRCERTCTX) RTCrStoreCertSearchNext(RTCRSTORE hStore, PRTCRSTORECERTSEARCH pSearch)
321{
322 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
323 AssertPtrReturn(pThis, NULL);
324 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, NULL);
325 AssertPtrReturn(pSearch, NULL);
326
327 PCRTCRCERTCTX pRet;
328 switch (pSearch->auOpaque[2])
329 {
330 default:
331 pRet = pThis->pProvider->pfnCertSearchNext(pThis->pvProvider, pSearch);
332 break;
333
334 case RTCRSTORECERTSEARCH_BY_SUBECT_OR_ALT_SUBJECT_BY_RFC5280:
335 {
336 PCRTCRX509NAME pSubject = (PCRTCRX509NAME)pSearch->auOpaque[3];
337 AssertPtrReturn(pSubject, NULL);
338
339 for (;;)
340 {
341 pRet = pThis->pProvider->pfnCertSearchNext(pThis->pvProvider, pSearch);
342 if (!pRet)
343 break;
344 if (pRet->pCert)
345 {
346 if (RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280(pRet->pCert, pSubject))
347 break;
348 }
349 else if (pRet->pTaInfo)
350 {
351 if ( RTCrTafCertPathControls_IsPresent(&pRet->pTaInfo->CertPath)
352 && RTCrX509Name_MatchByRfc5280(&pRet->pTaInfo->CertPath.TaName, pSubject))
353 break;
354 }
355 RTCrCertCtxRelease(pRet);
356 }
357 break;
358 }
359 }
360 return pRet;
361}
362
363
364RTDECL(int) RTCrStoreCertSearchDestroy(RTCRSTORE hStore, PRTCRSTORECERTSEARCH pSearch)
365{
366 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
367 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
368 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
369 if (pSearch)
370 {
371 AssertPtrReturn(pSearch, VERR_INVALID_POINTER);
372 pThis->pProvider->pfnCertSearchDestroy(pThis->pvProvider, pSearch);
373 }
374 return VINF_SUCCESS;
375}
376
377
378
379RTDECL(uint32_t) RTCrStoreCertCount(RTCRSTORE hStore)
380{
381 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
382 AssertPtrReturn(pThis, UINT32_MAX);
383 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, UINT32_MAX);
384
385 RTCRSTORECERTSEARCH Search;
386 int rc = pThis->pProvider->pfnCertFindAll(pThis->pvProvider, &Search);
387 AssertRCReturn(rc, UINT32_MAX);
388
389
390 uint32_t cCerts = 0;
391 PCRTCRCERTCTX pCur;
392 while ((pCur = pThis->pProvider->pfnCertSearchNext(pThis->pvProvider, &Search)) != NULL)
393 {
394 RTCrCertCtxRelease(pCur);
395 cCerts++;
396 }
397
398 return cCerts;
399}
400
401
402#ifdef IPRT_WITH_OPENSSL
403/*
404 * OpenSSL helper.
405 * OpenSSL helper.
406 * OpenSSL helper.
407 */
408
409RTDECL(int) RTCrStoreConvertToOpenSslCertStore(RTCRSTORE hStore, uint32_t fFlags, void **ppvOpenSslStore, PRTERRINFO pErrInfo)
410{
411 RT_NOREF(pErrInfo);
412 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
413 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
414 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
415 RT_NOREF_PV(fFlags);
416
417 /*
418 * Use the pfnCertFindAll method to add all certificates to the store we're returning.
419 */
420 int rc;
421 X509_STORE *pOsslStore = X509_STORE_new();
422 if (pOsslStore)
423 {
424 RTCRSTORECERTSEARCH Search;
425 rc = pThis->pProvider->pfnCertFindAll(pThis->pvProvider, &Search);
426 if (RT_SUCCESS(rc))
427 {
428 do
429 {
430 PCRTCRCERTCTX pCertCtx = pThis->pProvider->pfnCertSearchNext(pThis->pvProvider, &Search);
431 if (!pCertCtx)
432 break;
433
434 if ( (pCertCtx->fFlags & RTCRCERTCTX_F_ENC_MASK) == RTCRCERTCTX_F_ENC_X509_DER
435 && pCertCtx->cbEncoded > 0)
436 {
437 X509 *pOsslCert = NULL;
438 const unsigned char *pabEncoded = (const unsigned char *)pCertCtx->pabEncoded;
439 if (d2i_X509(&pOsslCert, &pabEncoded, pCertCtx->cbEncoded) == pOsslCert)
440 {
441 if (!X509_STORE_add_cert(pOsslStore, pOsslCert))
442 rc = VERR_NO_MEMORY;
443 X509_free(pOsslCert);
444 }
445 }
446
447 RTCrCertCtxRelease(pCertCtx);
448 } while (RT_SUCCESS(rc));
449
450 pThis->pProvider->pfnCertSearchDestroy(pThis->pvProvider, &Search);
451 if (RT_SUCCESS(rc))
452 {
453 *ppvOpenSslStore = pOsslStore;
454 return VINF_SUCCESS;
455 }
456 }
457 X509_STORE_free(pOsslStore);
458 }
459 else
460 rc = VERR_NO_MEMORY;
461 return rc;
462}
463
464
465RTDECL(int) RTCrStoreConvertToOpenSslCertStack(RTCRSTORE hStore, uint32_t fFlags, void **ppvOpenSslStack, PRTERRINFO pErrInfo)
466{
467 RT_NOREF(pErrInfo);
468 PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
469 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
470 AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
471 RT_NOREF_PV(fFlags);
472
473 /*
474 * Use the pfnCertFindAll method to add all certificates to the store we're returning.
475 */
476 int rc;
477 STACK_OF(X509) *pOsslStack = sk_X509_new_null();
478 if (pOsslStack)
479 {
480 RTCRSTORECERTSEARCH Search;
481 rc = pThis->pProvider->pfnCertFindAll(pThis->pvProvider, &Search);
482 if (RT_SUCCESS(rc))
483 {
484 do
485 {
486 PCRTCRCERTCTX pCertCtx = pThis->pProvider->pfnCertSearchNext(pThis->pvProvider, &Search);
487 if (!pCertCtx)
488 break;
489
490 if ( (pCertCtx->fFlags & RTCRCERTCTX_F_ENC_MASK) == RTCRCERTCTX_F_ENC_X509_DER
491 && pCertCtx->cbEncoded > 0)
492 {
493 X509 *pOsslCert = NULL;
494 const unsigned char *pabEncoded = (const unsigned char *)pCertCtx->pabEncoded;
495 if (d2i_X509(&pOsslCert, &pabEncoded, pCertCtx->cbEncoded) == pOsslCert)
496 {
497 if (!sk_X509_push(pOsslStack, pOsslCert))
498 {
499 rc = VERR_NO_MEMORY;
500 X509_free(pOsslCert);
501 }
502 }
503 }
504
505 RTCrCertCtxRelease(pCertCtx);
506 } while (RT_SUCCESS(rc));
507
508 pThis->pProvider->pfnCertSearchDestroy(pThis->pvProvider, &Search);
509 if (RT_SUCCESS(rc))
510 {
511 *ppvOpenSslStack = pOsslStack;
512 return VINF_SUCCESS;
513 }
514 }
515#include "internal/openssl-pre.h" /* Need to disable C5039 warning here. */
516 sk_X509_pop_free(pOsslStack, X509_free);
517#include "internal/openssl-post.h"
518 }
519 else
520 rc = VERR_NO_MEMORY;
521 return rc;
522}
523
524#endif /* IPRT_WITH_OPENSSL */
525
526
527/*
528 * Certificate context.
529 * Certificate context.
530 * Certificate context.
531 */
532
533
534RTDECL(uint32_t) RTCrCertCtxRetain(PCRTCRCERTCTX pCertCtx)
535{
536 AssertPtrReturn(pCertCtx, UINT32_MAX);
537 PRTCRCERTCTXINT pThis = RT_FROM_MEMBER(pCertCtx, RTCRCERTCTXINT, Public);
538 AssertReturn(pThis->u32Magic == RTCRCERTCTXINT_MAGIC, UINT32_MAX);
539 uint32_t cRet = ASMAtomicIncU32(&pThis->cRefs);
540 Assert(cRet < 64);
541 return cRet;
542}
543
544
545RTDECL(uint32_t) RTCrCertCtxRelease(PCRTCRCERTCTX pCertCtx)
546{
547 if (!pCertCtx)
548 return 0;
549
550 AssertPtrReturn(pCertCtx, UINT32_MAX);
551 PRTCRCERTCTXINT pThis = RT_FROM_MEMBER(pCertCtx, RTCRCERTCTXINT, Public);
552 AssertReturn(pThis->u32Magic == RTCRCERTCTXINT_MAGIC, UINT32_MAX);
553 uint32_t cRet = ASMAtomicDecU32(&pThis->cRefs);
554 if (!cRet)
555 {
556 ASMAtomicWriteU32(&pThis->u32Magic, RTCRCERTCTXINT_MAGIC_DEAD);
557 pThis->pfnDtor(pThis);
558 }
559 return cRet;
560}
561
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette