VirtualBox

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

Last change on this file since 84889 was 84329, checked in by vboxsync, 5 years ago

IPRT: Adding RTCrStoreCreateInMemEx that allows specifying a parent store to provide a kind of union store. bugref:9699

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