Coverage Report

Created: 2023-03-26 07:33

/src/gnutls/lib/x509/virt-san.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2015-2016 Nikos Mavrogiannopoulos
3
 * Copyright (C) 2015-2016 Red Hat, Inc.
4
 *
5
 * This file is part of GnuTLS.
6
 *
7
 * The GnuTLS is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation; either version 2.1 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
19
 *
20
 */
21
22
/* This file contains functions to handle the virtual subject alternative names,
23
 * based on othernames, such as GNUTLS_SAN_OTHERNAME_XMPP.
24
 */
25
26
#include "gnutls_int.h"
27
#include "x509_int.h"
28
#include "x509_ext_int.h"
29
#include "common.h"
30
#include "krb5.h"
31
#include "virt-san.h"
32
33
static
34
int san_othername_to_virtual(const char *oid, size_t size)
35
0
{
36
0
  if (oid) {
37
0
    if ((unsigned)size == (sizeof(XMPP_OID) - 1)
38
0
        && memcmp(oid, XMPP_OID, sizeof(XMPP_OID) - 1) == 0)
39
0
      return GNUTLS_SAN_OTHERNAME_XMPP;
40
0
    else if ((unsigned)size == (sizeof(KRB5_PRINCIPAL_OID) - 1)
41
0
       && memcmp(oid, KRB5_PRINCIPAL_OID,
42
0
           sizeof(KRB5_PRINCIPAL_OID) - 1) == 0)
43
0
      return GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL;
44
0
    else if ((unsigned)size ==
45
0
       (sizeof(MSUSER_PRINCIPAL_NAME_OID) - 1)
46
0
       && memcmp(oid, MSUSER_PRINCIPAL_NAME_OID,
47
0
           sizeof(MSUSER_PRINCIPAL_NAME_OID) - 1) == 0)
48
0
      return GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL;
49
0
  }
50
51
0
  return GNUTLS_SAN_OTHERNAME;
52
0
}
53
54
static
55
const char *virtual_to_othername_oid(unsigned type)
56
0
{
57
0
  switch (type) {
58
0
  case GNUTLS_SAN_OTHERNAME_XMPP:
59
0
    return XMPP_OID;
60
0
  case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
61
0
    return KRB5_PRINCIPAL_OID;
62
0
  case GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL:
63
0
    return MSUSER_PRINCIPAL_NAME_OID;
64
0
  default:
65
0
    return NULL;
66
0
  }
67
0
}
68
69
int _gnutls_alt_name_assign_virt_type(struct name_st *name, unsigned type,
70
              gnutls_datum_t * san,
71
              const char *othername_oid, unsigned raw)
72
0
{
73
0
  gnutls_datum_t encoded = { NULL, 0 };
74
0
  gnutls_datum_t xmpp = { NULL, 0 };
75
0
  int ret;
76
77
0
  if (type < 1000) {
78
0
    name->type = type;
79
0
    ret = _gnutls_alt_name_process(&name->san, type, san, raw);
80
0
    if (ret < 0)
81
0
      return gnutls_assert_val(ret);
82
0
    gnutls_free(san->data);
83
84
0
    if (othername_oid) {
85
0
      name->othername_oid.data = (uint8_t *) othername_oid;
86
0
      name->othername_oid.size = strlen(othername_oid);
87
0
    } else {
88
0
      name->othername_oid.data = NULL;
89
0
      name->othername_oid.size = 0;
90
0
    }
91
0
  } else {   /* virtual types */
92
0
    const char *oid = virtual_to_othername_oid(type);
93
94
0
    if (oid == NULL)
95
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
96
97
0
    switch (type) {
98
0
    case GNUTLS_SAN_OTHERNAME_XMPP:
99
100
0
      ret =
101
0
          gnutls_idna_map((char *)san->data, san->size, &xmpp,
102
0
              0);
103
0
      if (ret < 0)
104
0
        return gnutls_assert_val(ret);
105
106
0
      ret = _gnutls_x509_encode_string(ASN1_ETYPE_UTF8_STRING,
107
0
               xmpp.data, xmpp.size,
108
0
               &encoded);
109
110
0
      gnutls_free(xmpp.data);
111
0
      if (ret < 0)
112
0
        return gnutls_assert_val(ret);
113
114
0
      name->type = GNUTLS_SAN_OTHERNAME;
115
0
      name->san.data = encoded.data;
116
0
      name->san.size = encoded.size;
117
0
      name->othername_oid.data = (void *)gnutls_strdup(oid);
118
0
      name->othername_oid.size = strlen(oid);
119
0
      break;
120
121
0
    case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
122
0
      ret =
123
0
          _gnutls_krb5_principal_to_der((char *)san->data,
124
0
                &name->san);
125
0
      if (ret < 0)
126
0
        return gnutls_assert_val(ret);
127
128
0
      name->othername_oid.data = (void *)gnutls_strdup(oid);
129
0
      name->othername_oid.size = strlen(oid);
130
0
      name->type = GNUTLS_SAN_OTHERNAME;
131
0
      break;
132
133
0
    default:
134
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
135
0
    }
136
137
0
    gnutls_free(san->data);
138
0
  }
139
140
0
  return 0;
141
0
}
142
143
/**
144
 * gnutls_x509_othername_to_virtual:
145
 * @oid: The othername object identifier
146
 * @othername: The othername data
147
 * @virt_type: GNUTLS_SAN_OTHERNAME_XXX
148
 * @virt: allocated printable data
149
 *
150
 * This function will parse and convert the othername data to a virtual
151
 * type supported by gnutls.
152
 *
153
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
154
 *
155
 * Since: 3.3.8
156
 **/
157
int gnutls_x509_othername_to_virtual(const char *oid,
158
             const gnutls_datum_t * othername,
159
             unsigned int *virt_type,
160
             gnutls_datum_t * virt)
161
0
{
162
0
  int ret;
163
0
  unsigned type;
164
165
0
  type = san_othername_to_virtual(oid, strlen(oid));
166
0
  if (type == GNUTLS_SAN_OTHERNAME)
167
0
    return gnutls_assert_val(GNUTLS_E_X509_UNKNOWN_SAN);
168
169
0
  if (virt_type)
170
0
    *virt_type = type;
171
172
0
  switch (type) {
173
0
  case GNUTLS_SAN_OTHERNAME_XMPP:
174
0
    ret = _gnutls_x509_decode_string
175
0
        (ASN1_ETYPE_UTF8_STRING, othername->data,
176
0
         othername->size, virt, 0);
177
0
    if (ret < 0) {
178
0
      gnutls_assert();
179
0
      return ret;
180
0
    }
181
0
    return 0;
182
0
  case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
183
0
    ret = _gnutls_krb5_der_to_principal(othername, virt);
184
0
    if (ret < 0) {
185
0
      gnutls_assert();
186
0
      return ret;
187
0
    }
188
0
    return 0;
189
0
  case GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL:
190
0
    ret = _gnutls_x509_decode_string
191
0
        (ASN1_ETYPE_UTF8_STRING, othername->data,
192
0
         othername->size, virt, 0);
193
0
    if (ret < 0) {
194
0
      gnutls_assert();
195
0
      return ret;
196
0
    }
197
0
    return 0;
198
0
  default:
199
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
200
0
  }
201
0
}