VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTCrX509-1.cpp@ 65892

Last change on this file since 65892 was 62461, checked in by vboxsync, 8 years ago

IPRT: scm

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1/* $Id: tstRTCrX509-1.cpp 62461 2016-07-22 16:21:26Z vboxsync $ */
2/** @file
3 * IPRT testcase - Crypto - X.509 \#1.
4 */
5
6/*
7 * Copyright (C) 2016 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 <iprt/crypto/x509.h>
32
33#include <iprt/string.h>
34#include <iprt/test.h>
35
36#include "tstRTCrX509-1.h"
37
38
39/*********************************************************************************************************************************
40* Global Variables *
41*********************************************************************************************************************************/
42static RTTEST g_hTest;
43
44/** List of test certificates + keys, PEM encoding, and their corresponding
45 * .der certificate encodings. */
46static const struct
47{
48 const char *pszFile;
49 bool fMaybeNotInOpenSSL;
50 bool fSelfSigned;
51
52 char const *pchPem;
53 size_t cbPem;
54
55 uint8_t const *pbDer;
56 size_t cbDer;
57} g_aFiles[] =
58{
59#define MY_CERT_ENTRY(a_fMaybeNotInOpenSSL, a_fSelfSigned, a_Name) \
60 { #a_Name, a_fMaybeNotInOpenSSL, a_fSelfSigned, \
61 (const char *)RT_CONCAT(g_abPem_, a_Name), RT_CONCAT(g_cbPem_, a_Name), \
62 RT_CONCAT(g_abDer_, a_Name), RT_CONCAT(g_cbDer_, a_Name) }
63 MY_CERT_ENTRY(true, true, md4),
64 MY_CERT_ENTRY(false, true, md5),
65 MY_CERT_ENTRY(false, true, sha1),
66 MY_CERT_ENTRY(false, true, sha224),
67 MY_CERT_ENTRY(false, true, sha256),
68 MY_CERT_ENTRY(false, true, sha384),
69 MY_CERT_ENTRY(false, true, sha512),
70 MY_CERT_ENTRY(false, false, cert1),
71};
72
73
74static void test1()
75{
76 RTTestSub(g_hTest, "Basics");
77 int rc;
78 for (unsigned i = 0; i < RT_ELEMENTS(g_aFiles); i++)
79 {
80 /*
81 * Decode.
82 */
83 /* Raw decoding of DER bytes, structure will have pointers to the raw data. */
84 RTCRX509CERTIFICATE Cert0;
85 RTASN1CURSORPRIMARY PrimaryCursor;
86 RTAsn1CursorInitPrimary(&PrimaryCursor, g_aFiles[i].pbDer, (uint32_t)g_aFiles[i].cbDer,
87 NULL /*pErrInfo*/, &g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, NULL /*pszErrorTag*/);
88 rc = RTCrX509Certificate_DecodeAsn1(&PrimaryCursor.Cursor, 0, &Cert0, "Cert0");
89 if (RT_SUCCESS(rc))
90 {
91 rc = RTCrX509Certificate_CheckSanity(&Cert0, 0, NULL /*pErrInfo*/, "Cert0");
92 if (RT_SUCCESS(rc))
93 {
94 /* Check the API, this clones the certificate so no data pointers. */
95 RTCRX509CERTIFICATE Cert1;
96 memset(&Cert1, i, sizeof(Cert1));
97 rc = RTCrX509Certificate_ReadFromBuffer(&Cert1, g_aFiles[i].pbDer, g_aFiles[i].cbDer, 0 /*fFlags*/,
98 &g_RTAsn1EFenceAllocator, NULL /*pErrInfo*/, NULL /*pszErrorTag*/);
99 if (RT_SUCCESS(rc))
100 {
101 /* Read the PEM variant. */
102 RTCRX509CERTIFICATE Cert2;
103 memset(&Cert2, ~i, sizeof(Cert2));
104 rc = RTCrX509Certificate_ReadFromBuffer(&Cert2, g_aFiles[i].pchPem, g_aFiles[i].cbPem, 0 /*fFlags*/,
105 &g_RTAsn1DefaultAllocator, NULL /*pErrInfo*/, NULL /*pszErrorTag*/);
106 if (RT_SUCCESS(rc))
107 {
108 /*
109 * Compare them, they should be all the same.
110 */
111 if (RTCrX509Certificate_Compare(&Cert0, &Cert1) != 0)
112 RTTestIFailed("Cert0 and Cert1 (DER) decoding of file %s (#%u) differs", g_aFiles[i].pszFile, i);
113 else if (RTCrX509Certificate_Compare(&Cert0, &Cert2) != 0)
114 RTTestIFailed("Cert0 and Cert2 (PEM) decoding of file %s (#%u) differs", g_aFiles[i].pszFile, i);
115 else if (RTCrX509Certificate_Compare(&Cert1, &Cert2) != 0)
116 RTTestIFailed("Cert1 (DER) and Cert2 (PEM) decoding of file %s (#%u) differs", g_aFiles[i].pszFile, i);
117 else
118 {
119 /*
120 * Encode the certificates.
121 */
122 unsigned j;
123 PRTCRX509CERTIFICATE paCerts[] = { &Cert0, &Cert1, &Cert2 };
124 for (j = 0; j < RT_ELEMENTS(paCerts); j++)
125 {
126 uint32_t cbEncoded = ~(j ^ i);
127 RTTESTI_CHECK_RC(rc = RTAsn1EncodePrepare(&paCerts[j]->SeqCore.Asn1Core,
128 RTASN1ENCODE_F_DER, &cbEncoded, NULL), VINF_SUCCESS);
129 if (RT_SUCCESS(rc) && cbEncoded != g_aFiles[i].cbDer)
130 RTTestIFailed("RTAsn1EncodePrepare of file %s (#%u) returned %#x bytes instead of %#x",
131 g_aFiles[i].pszFile, i, cbEncoded, g_aFiles[i].cbDer);
132
133 cbEncoded = (uint32_t)g_aFiles[i].cbDer;
134 void *pvTmp = RTTestGuardedAllocTail(g_hTest, cbEncoded);
135 RTTESTI_CHECK_RC(rc = RTAsn1EncodeToBuffer(&paCerts[j]->SeqCore.Asn1Core, RTASN1ENCODE_F_DER,
136 pvTmp, cbEncoded, NULL /*pErrInfo*/), VINF_SUCCESS);
137 if (RT_SUCCESS(rc) && memcmp(pvTmp, g_aFiles[i].pbDer, cbEncoded) != 0)
138 RTTestIFailed("RTAsn1EncodeToBuffer produces the wrong output for file %s (#%u), variation %u",
139 g_aFiles[i].pszFile, i, j);
140 RTTestGuardedFree(g_hTest, pvTmp);
141 }
142
143 /*
144 * Check that our self signed check works.
145 */
146 RTTESTI_CHECK(RTCrX509Certificate_IsSelfSigned(&Cert0) == g_aFiles[i].fSelfSigned);
147 RTTESTI_CHECK(RTCrX509Certificate_IsSelfSigned(&Cert1) == g_aFiles[i].fSelfSigned);
148 RTTESTI_CHECK(RTCrX509Certificate_IsSelfSigned(&Cert2) == g_aFiles[i].fSelfSigned);
149
150 if (g_aFiles[i].fSelfSigned)
151 {
152 /*
153 * Verify the certificate signature (self signed).
154 */
155 for (j = 0; j < RT_ELEMENTS(paCerts); j++)
156 {
157 rc = RTCrX509Certificate_VerifySignatureSelfSigned(paCerts[j], NULL /*pErrInfo*/);
158 if ( RT_FAILURE(rc)
159 && ( rc != VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP
160 || !g_aFiles[i].fMaybeNotInOpenSSL) )
161 RTTestIFailed("RTCrX509Certificate_VerifySignatureSelfSigned failed for %s (#%u), variation %u: %Rrc",
162 g_aFiles[i].pszFile, i, j, rc);
163 }
164 }
165 }
166
167 RTCrX509Certificate_Delete(&Cert2);
168 }
169 else
170 RTTestIFailed("Error %Rrc decoding PEM file %s (#%u)", rc, g_aFiles[i].pszFile, i);
171 RTCrX509Certificate_Delete(&Cert1);
172 }
173 else
174 RTTestIFailed("Error %Rrc decoding DER file %s (#%u)", rc, g_aFiles[i].pszFile, i);
175 }
176 RTCrX509Certificate_Delete(&Cert0);
177 }
178 }
179}
180
181
182
183
184int main()
185{
186 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTCrX509-1", &g_hTest);
187 if (rcExit != RTEXITCODE_SUCCESS)
188 return rcExit;
189 RTTestBanner(g_hTest);
190
191 test1();
192
193
194 return RTTestSummaryAndDestroy(g_hTest);
195}
196
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