VirtualBox

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

Last change on this file since 96407 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

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