1/* $OpenBSD: x509_set.c,v 1.29 2024/03/26 23:21:36 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/evp.h>
63#include <openssl/objects.h>
64#include <openssl/x509.h>
65
66#include "x509_local.h"
67
68const STACK_OF(X509_EXTENSION) *
69X509_get0_extensions(const X509 *x)
70{
71	return x->cert_info->extensions;
72}
73LCRYPTO_ALIAS(X509_get0_extensions);
74
75const X509_ALGOR *
76X509_get0_tbs_sigalg(const X509 *x)
77{
78	return x->cert_info->signature;
79}
80LCRYPTO_ALIAS(X509_get0_tbs_sigalg);
81
82int
83X509_set_version(X509 *x, long version)
84{
85	if (x == NULL)
86		return 0;
87	/*
88	 * RFC 5280, 4.1: versions 1 - 3 are specified as follows.
89	 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2) }
90	 */
91	if (version < 0 || version > 2)
92		return 0;
93	if (x->cert_info->version == NULL) {
94		if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL)
95			return 0;
96	}
97	x->cert_info->enc.modified = 1;
98	return ASN1_INTEGER_set(x->cert_info->version, version);
99}
100LCRYPTO_ALIAS(X509_set_version);
101
102long
103X509_get_version(const X509 *x)
104{
105	return ASN1_INTEGER_get(x->cert_info->version);
106}
107LCRYPTO_ALIAS(X509_get_version);
108
109int
110X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
111{
112	ASN1_INTEGER *in;
113
114	if (x == NULL)
115		return 0;
116	in = x->cert_info->serialNumber;
117	if (in != serial) {
118		in = ASN1_INTEGER_dup(serial);
119		if (in != NULL) {
120			x->cert_info->enc.modified = 1;
121			ASN1_INTEGER_free(x->cert_info->serialNumber);
122			x->cert_info->serialNumber = in;
123		}
124	}
125	return in != NULL;
126}
127LCRYPTO_ALIAS(X509_set_serialNumber);
128
129int
130X509_set_issuer_name(X509 *x, X509_NAME *name)
131{
132	if (x == NULL || x->cert_info == NULL)
133		return 0;
134	x->cert_info->enc.modified = 1;
135	return X509_NAME_set(&x->cert_info->issuer, name);
136}
137LCRYPTO_ALIAS(X509_set_issuer_name);
138
139int
140X509_set_subject_name(X509 *x, X509_NAME *name)
141{
142	if (x == NULL || x->cert_info == NULL)
143		return 0;
144	x->cert_info->enc.modified = 1;
145	return X509_NAME_set(&x->cert_info->subject, name);
146}
147LCRYPTO_ALIAS(X509_set_subject_name);
148
149const ASN1_TIME *
150X509_get0_notBefore(const X509 *x)
151{
152	return X509_getm_notBefore(x);
153}
154LCRYPTO_ALIAS(X509_get0_notBefore);
155
156ASN1_TIME *
157X509_getm_notBefore(const X509 *x)
158{
159	if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL)
160		return NULL;
161	return x->cert_info->validity->notBefore;
162}
163LCRYPTO_ALIAS(X509_getm_notBefore);
164
165int
166X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
167{
168	ASN1_TIME *in;
169
170	if (x == NULL || x->cert_info->validity == NULL)
171		return 0;
172	in = x->cert_info->validity->notBefore;
173	if (in != tm) {
174		in = ASN1_STRING_dup(tm);
175		if (in != NULL) {
176			x->cert_info->enc.modified = 1;
177			ASN1_TIME_free(x->cert_info->validity->notBefore);
178			x->cert_info->validity->notBefore = in;
179		}
180	}
181	return in != NULL;
182}
183LCRYPTO_ALIAS(X509_set_notBefore);
184
185int
186X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
187{
188	return X509_set_notBefore(x, tm);
189}
190LCRYPTO_ALIAS(X509_set1_notBefore);
191
192const ASN1_TIME *
193X509_get0_notAfter(const X509 *x)
194{
195	return X509_getm_notAfter(x);
196}
197LCRYPTO_ALIAS(X509_get0_notAfter);
198
199ASN1_TIME *
200X509_getm_notAfter(const X509 *x)
201{
202	if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL)
203		return NULL;
204	return x->cert_info->validity->notAfter;
205}
206LCRYPTO_ALIAS(X509_getm_notAfter);
207
208int
209X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
210{
211	ASN1_TIME *in;
212
213	if (x == NULL || x->cert_info->validity == NULL)
214		return 0;
215	in = x->cert_info->validity->notAfter;
216	if (in != tm) {
217		in = ASN1_STRING_dup(tm);
218		if (in != NULL) {
219			x->cert_info->enc.modified = 1;
220			ASN1_TIME_free(x->cert_info->validity->notAfter);
221			x->cert_info->validity->notAfter = in;
222		}
223	}
224	return in != NULL;
225}
226LCRYPTO_ALIAS(X509_set_notAfter);
227
228int
229X509_set1_notAfter(X509 *x, const ASN1_TIME *tm)
230{
231	return X509_set_notAfter(x, tm);
232}
233LCRYPTO_ALIAS(X509_set1_notAfter);
234
235int
236X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
237{
238	if (x == NULL || x->cert_info == NULL)
239		return 0;
240	x->cert_info->enc.modified = 1;
241	return X509_PUBKEY_set(&x->cert_info->key, pkey);
242}
243LCRYPTO_ALIAS(X509_set_pubkey);
244
245int
246X509_get_signature_type(const X509 *x)
247{
248	return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg->algorithm));
249}
250LCRYPTO_ALIAS(X509_get_signature_type);
251
252X509_PUBKEY *
253X509_get_X509_PUBKEY(const X509 *x)
254{
255	return x->cert_info->key;
256}
257LCRYPTO_ALIAS(X509_get_X509_PUBKEY);
258
259void
260X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **issuerUID,
261    const ASN1_BIT_STRING **subjectUID)
262{
263	if (issuerUID != NULL)
264		*issuerUID = x->cert_info->issuerUID;
265	if (subjectUID != NULL)
266		*subjectUID = x->cert_info->subjectUID;
267}
268LCRYPTO_ALIAS(X509_get0_uids);
269