VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/crypto/x509-sanity.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1/* $Id: x509-sanity.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * IPRT - Crypto - X.509, Sanity Checkers.
4 */
5
6/*
7 * Copyright (C) 2006-2023 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/x509.h>
43
44#include <iprt/err.h>
45#include <iprt/string.h>
46
47#include "x509-internal.h"
48
49
50
51static int rtCrX509Validity_CheckSanityExtra(PCRTCRX509VALIDITY pThis, uint32_t fFlags, PRTERRINFO pErrInfo, const char *pszErrorTag)
52{
53 RT_NOREF_PV(fFlags);
54
55 if (RTAsn1Time_Compare(&pThis->NotBefore, &pThis->NotAfter) > 0)
56 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_VALIDITY_SWAPPED, "%s: NotBefore is after NotAfter", pszErrorTag);
57 /** @todo check tag constraints? */
58 return VINF_SUCCESS;
59}
60
61
62static int rtCrX509Name_CheckSanityExtra(PCRTCRX509NAME pThis, uint32_t fFlags, PRTERRINFO pErrInfo, const char *pszErrorTag)
63{
64 RT_NOREF_PV(fFlags);
65
66 if (pThis->cItems == 0)
67 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_SET, "%s: Has no components.", pszErrorTag);
68
69 for (uint32_t i = 0; i < pThis->cItems; i++)
70 {
71 PCRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = pThis->papItems[i];
72 if (pRdn->cItems == 0)
73 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_SUB_SET,
74 "%s: Items[%u] has no sub components.", pszErrorTag, i);
75
76 for (uint32_t j = 0; j < pRdn->cItems; j++)
77 {
78 PCRTCRX509ATTRIBUTETYPEANDVALUE const pAttr = pRdn->papItems[j];
79
80 if (pAttr->Value.enmType != RTASN1TYPE_STRING)
81 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_NOT_STRING,
82 "%s: Items[%u].paItems[%u].enmType is %d instead of string (%d).",
83 pszErrorTag, i, j, pAttr->Value.enmType, RTASN1TYPE_STRING);
84 if (pAttr->Value.u.String.Asn1Core.cb == 0)
85 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_STRING,
86 "%s: Items[%u].paItems[%u] is an empty string", pszErrorTag, i, j);
87 switch (pAttr->Value.u.String.Asn1Core.uTag)
88 {
89 case ASN1_TAG_PRINTABLE_STRING:
90 case ASN1_TAG_UTF8_STRING:
91 break;
92 case ASN1_TAG_T61_STRING:
93 case ASN1_TAG_UNIVERSAL_STRING:
94 case ASN1_TAG_BMP_STRING:
95 break;
96 case ASN1_TAG_IA5_STRING: /* Used by "Microsoft Root Certificate Authority" in the "com" part of the Issuer. */
97 break;
98 default:
99 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_INVALID_NAME_STRING_TAG,
100 "%s: Items[%u].paItems[%u] invalid string type: %u", pszErrorTag, i, j,
101 pAttr->Value.u.String.Asn1Core.uTag);
102 }
103 }
104 }
105
106 return VINF_SUCCESS;
107}
108
109
110static int rtCrX509SubjectPublicKeyInfo_CheckSanityExtra(PCRTCRX509SUBJECTPUBLICKEYINFO pThis, uint32_t fFlags,
111 PRTERRINFO pErrInfo, const char *pszErrorTag)
112{
113 RT_NOREF_PV(fFlags);
114 if (pThis->SubjectPublicKey.cBits <= 32)
115 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_PUBLIC_KEY_TOO_SMALL,
116 "%s: SubjectPublicKey is too small, only %u bits", pszErrorTag, pThis->SubjectPublicKey.cBits);
117 return VINF_SUCCESS;
118}
119
120
121static int rtCrX509TbsCertificate_CheckSanityExtra(PCRTCRX509TBSCERTIFICATE pThis, uint32_t fFlags,
122 PRTERRINFO pErrInfo, const char *pszErrorTag)
123{
124 RT_NOREF_PV(fFlags);
125
126 if ( RTAsn1Integer_IsPresent(&pThis->T0.Version)
127 && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V1) != 0
128 && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V2) != 0
129 && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V3) != 0)
130 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_UNSUPPORTED_VERSION,
131 "%s: Unknown Version number: %llu",
132 pszErrorTag, pThis->T0.Version.uValue.u);
133
134 if ( pThis->SerialNumber.Asn1Core.cb < 1
135 || pThis->SerialNumber.Asn1Core.cb > 1024)
136 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_SERIAL_NUMBER_OUT_OF_BOUNDS,
137 "%s: Bad SerialNumber length: %u", pszErrorTag, pThis->SerialNumber.Asn1Core.cb);
138
139 if ( ( RTAsn1BitString_IsPresent(&pThis->T1.IssuerUniqueId)
140 || RTAsn1BitString_IsPresent(&pThis->T2.SubjectUniqueId))
141 && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V2) < 0)
142 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_UNIQUE_IDS_REQ_V2,
143 "%s: IssuerUniqueId and SubjectUniqueId requires version 2", pszErrorTag);
144
145 if ( RTCrX509Extensions_IsPresent(&pThis->T3.Extensions)
146 && RTAsn1Integer_UnsignedCompareWithU32(&pThis->T0.Version, RTCRX509TBSCERTIFICATE_V3) < 0)
147 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_TBSCERT_EXTS_REQ_V3, "%s: Extensions requires version 3", pszErrorTag);
148
149 return VINF_SUCCESS;
150}
151
152
153static int rtCrX509Certificate_CheckSanityExtra(PCRTCRX509CERTIFICATE pThis, uint32_t fFlags,
154 PRTERRINFO pErrInfo, const char *pszErrorTag)
155{
156 RT_NOREF_PV(fFlags);
157
158 if (RTCrX509AlgorithmIdentifier_Compare(&pThis->SignatureAlgorithm, &pThis->TbsCertificate.Signature) != 0)
159 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_CERT_TBS_SIGN_ALGO_MISMATCH,
160 "%s: SignatureAlgorithm (%s) does not match TbsCertificate.Signature (%s).", pszErrorTag,
161 pThis->SignatureAlgorithm.Algorithm.szObjId,
162 pThis->TbsCertificate.Signature.Algorithm.szObjId);
163 return VINF_SUCCESS;
164}
165
166
167/*
168 * Generate the code.
169 */
170#include <iprt/asn1-generator-sanity.h>
171
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use