x509_set.c 5.7 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9 10
 */

#include <stdio.h>
11
#include "internal/cryptlib.h"
12 13 14 15
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
16 17
#include <openssl/x509v3.h>
#include "internal/asn1_int.h"
D
Dr. Stephen Henson 已提交
18
#include "internal/x509_int.h"
19
#include "x509_lcl.h"
20

U
Ulf Möller 已提交
21
int X509_set_version(X509 *x, long version)
22 23 24 25
{
    if (x == NULL)
        return (0);
    if (version == 0) {
D
Dr. Stephen Henson 已提交
26 27
        ASN1_INTEGER_free(x->cert_info.version);
        x->cert_info.version = NULL;
28 29
        return (1);
    }
D
Dr. Stephen Henson 已提交
30 31
    if (x->cert_info.version == NULL) {
        if ((x->cert_info.version = ASN1_INTEGER_new()) == NULL)
32 33
            return (0);
    }
D
Dr. Stephen Henson 已提交
34
    return (ASN1_INTEGER_set(x->cert_info.version, version));
35
}
36

U
Ulf Möller 已提交
37
int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
38 39
{
    ASN1_INTEGER *in;
40

41
    if (x == NULL)
42 43 44 45 46
        return 0;
    in = &x->cert_info.serialNumber;
    if (in != serial)
        return ASN1_STRING_copy(in, serial);
    return 1;
47
}
48

U
Ulf Möller 已提交
49
int X509_set_issuer_name(X509 *x, X509_NAME *name)
50
{
D
Dr. Stephen Henson 已提交
51
    if (x == NULL)
52
        return (0);
D
Dr. Stephen Henson 已提交
53
    return (X509_NAME_set(&x->cert_info.issuer, name));
54
}
55

U
Ulf Möller 已提交
56
int X509_set_subject_name(X509 *x, X509_NAME *name)
57
{
D
Dr. Stephen Henson 已提交
58
    if (x == NULL)
59
        return (0);
D
Dr. Stephen Henson 已提交
60
    return (X509_NAME_set(&x->cert_info.subject, name));
61
}
62

D
Dr. Stephen Henson 已提交
63
int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm)
64 65
{
    ASN1_TIME *in;
D
Dr. Stephen Henson 已提交
66
    in = *ptm;
67
    if (in != tm) {
D
Dr. Stephen Henson 已提交
68
        in = ASN1_STRING_dup(tm);
69
        if (in != NULL) {
D
Dr. Stephen Henson 已提交
70 71
            ASN1_TIME_free(*ptm);
            *ptm = in;
72 73 74 75
        }
    }
    return (in != NULL);
}
76

77
int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
78
{
D
Dr. Stephen Henson 已提交
79 80 81 82
    if (x == NULL)
        return 0;
    return x509_set1_time(&x->cert_info.validity.notBefore, tm);
}
83

84
int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm)
D
Dr. Stephen Henson 已提交
85
{
86
    if (x == NULL)
D
Dr. Stephen Henson 已提交
87 88
        return 0;
    return x509_set1_time(&x->cert_info.validity.notAfter, tm);
89
}
90

U
Ulf Möller 已提交
91
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
92
{
D
Dr. Stephen Henson 已提交
93
    if (x == NULL)
94
        return (0);
D
Dr. Stephen Henson 已提交
95
    return (X509_PUBKEY_set(&(x->cert_info.key), pkey));
96
}
D
Dr. Stephen Henson 已提交
97

98
int X509_up_ref(X509 *x)
D
Dr. Stephen Henson 已提交
99
{
100
    int i;
101

102
    if (CRYPTO_UP_REF(&x->references, &i, x->lock) <= 0)
103 104 105 106 107
        return 0;

    REF_PRINT_COUNT("X509", x);
    REF_ASSERT_ISNT(i < 2);
    return ((i > 1) ? 1 : 0);
D
Dr. Stephen Henson 已提交
108
}
109

110
long X509_get_version(const X509 *x)
111
{
D
Dr. Stephen Henson 已提交
112
    return ASN1_INTEGER_get(x->cert_info.version);
113 114
}

115 116 117 118 119 120 121 122 123 124
const ASN1_TIME *X509_get0_notBefore(const X509 *x)
{
    return x->cert_info.validity.notBefore;
}

const ASN1_TIME *X509_get0_notAfter(const X509 *x)
{
    return x->cert_info.validity.notAfter;
}

125
ASN1_TIME *X509_getm_notBefore(const X509 *x)
126
{
D
Dr. Stephen Henson 已提交
127
    return x->cert_info.validity.notBefore;
128 129
}

130
ASN1_TIME *X509_getm_notAfter(const X509 *x)
131
{
D
Dr. Stephen Henson 已提交
132
    return x->cert_info.validity.notAfter;
133 134 135 136
}

int X509_get_signature_type(const X509 *x)
{
137
    return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg.algorithm));
138 139 140 141
}

X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x)
{
D
Dr. Stephen Henson 已提交
142
    return x->cert_info.key;
143
}
D
Dr. Stephen Henson 已提交
144

145
const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x)
D
Dr. Stephen Henson 已提交
146 147 148 149
{
    return x->cert_info.extensions;
}

150 151
void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
                    const ASN1_BIT_STRING **psuid)
D
Dr. Stephen Henson 已提交
152 153 154 155 156 157 158
{
    if (piuid != NULL)
        *piuid = x->cert_info.issuerUID;
    if (psuid != NULL)
        *psuid = x->cert_info.subjectUID;
}

159
const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
D
Dr. Stephen Henson 已提交
160 161 162
{
    return &x->cert_info.signature;
}
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid,
                      int *secbits, uint32_t *flags)
{
    if (mdnid != NULL)
        *mdnid = siginf->mdnid;
    if (pknid != NULL)
        *pknid = siginf->pknid;
    if (secbits != NULL)
        *secbits = siginf->secbits;
    if (flags != NULL)
        *flags = siginf->flags;
    return (siginf->flags & X509_SIG_INFO_VALID) != 0;
}

void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
                       int secbits, uint32_t flags)
{
    siginf->mdnid = mdnid;
    siginf->pknid = pknid;
    siginf->secbits = secbits;
    siginf->flags = flags;
}

int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
                            uint32_t *flags)
{
    X509_check_purpose(x, -1, -1);
    return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags);
}

static void x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
                               const ASN1_STRING *sig)
{
    int pknid, mdnid;
    const EVP_MD *md;

    siginf->mdnid = NID_undef;
    siginf->pknid = NID_undef;
    siginf->secbits = -1;
    siginf->flags = 0;
    if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)
            || pknid == NID_undef)
        return;
    siginf->pknid = pknid;
    if (mdnid == NID_undef) {
        /* If we have one, use a custom handler for this algorithm */
        const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, pknid);
        if (ameth == NULL || ameth->siginf_set == NULL
                || ameth->siginf_set(siginf, alg, sig) == 0)
            return;
        siginf->flags |= X509_SIG_INFO_VALID;
        return;
    }
    siginf->flags |= X509_SIG_INFO_VALID;
    siginf->mdnid = mdnid;
    md = EVP_get_digestbynid(mdnid);
    if (md == NULL)
        return;
    /* Security bits: half number of bits in digest */
    siginf->secbits = EVP_MD_size(md) * 4;
    switch (mdnid) {
        case NID_sha1:
        case NID_sha256:
        case NID_sha384:
        case NID_sha512:
        siginf->flags |= X509_SIG_INFO_TLS;
    }
}

void x509_init_sig_info(X509 *x)
{
    x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
}