VirtualBox

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

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

IPRT/crypto: Adding RTAsn1EncodeQueryRawBits to deal with getting encoded bytes cheaply if possible and always safely. Fixed another place using RTASN1CORE_GET_RAW_ASN1_PTR and assuming input was decoded and had valid data pointers. Added RTCrStoreCertAddPkcs7 and RTCrStoreCertAddX509 for more conveniently adding decoded certs to stores. Added RTCRPKCS7VERIFY_SD_F_TRUST_ALL_CERTS to the PKCS7 verification code. Added RTCrPkcs7_ReadFromBuffer. bugref:9699

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

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