Line data Source code
1 : /* 2 : * Copyright (C) 2015 Red Hat, Inc. 3 : * 4 : * Author: Nikos Mavrogiannopoulos 5 : * 6 : * This file is part of GnuTLS. 7 : * 8 : * The GnuTLS is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU Lesser General Public License 10 : * as published by the Free Software Foundation; either version 2.1 of 11 : * the License, or (at your option) any later version. 12 : * 13 : * This library is distributed in the hope that it will be useful, but 14 : * WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 : * Lesser General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public License 19 : * along with this program. If not, see <https://www.gnu.org/licenses/> 20 : * 21 : */ 22 : 23 : /* Functions that relate on PKCS7 attribute setting. 24 : */ 25 : 26 : #include "gnutls_int.h" 27 : 28 : #include <datum.h> 29 : #include <global.h> 30 : #include "errors.h" 31 : #include <common.h> 32 : #include <x509_b64.h> 33 : #include <gnutls/abstract.h> 34 : #include <gnutls/pkcs7.h> 35 : 36 : /** 37 : * gnutls_pkcs7_add_attr: 38 : * @list: A list of existing attributes or pointer to %NULL for the first one 39 : * @oid: the OID of the attribute to be set 40 : * @data: the raw (DER-encoded) data of the attribute to be set 41 : * @flags: zero or %GNUTLS_PKCS7_ATTR_ENCODE_OCTET_STRING 42 : * 43 : * This function will set a PKCS #7 attribute in the provided list. 44 : * If this function fails, the previous list would be deallocated. 45 : * 46 : * Note that any attributes set with this function must either be 47 : * DER or BER encoded, unless a special flag is present. 48 : * 49 : * Returns: On success, the new list head, otherwise %NULL. 50 : * 51 : * Since: 3.4.2 52 : **/ 53 : int 54 228 : gnutls_pkcs7_add_attr(gnutls_pkcs7_attrs_t * list, const char *oid, 55 : gnutls_datum_t * data, unsigned flags) 56 : { 57 228 : int ret; 58 228 : gnutls_pkcs7_attrs_st *r; 59 : 60 228 : r = gnutls_calloc(1, sizeof(gnutls_pkcs7_attrs_st)); 61 228 : if (r == NULL) 62 0 : goto fail; 63 : 64 228 : if (flags & GNUTLS_PKCS7_ATTR_ENCODE_OCTET_STRING) { 65 3 : ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING, 66 3 : data->data, data->size, 67 : &r->data); 68 : } else { 69 225 : ret = _gnutls_set_datum(&r->data, data->data, data->size); 70 : } 71 228 : if (ret < 0) 72 0 : goto fail; 73 : 74 228 : r->oid = gnutls_strdup(oid); 75 228 : if (r->oid == NULL) 76 0 : goto fail; 77 : 78 228 : r->next = *list; 79 228 : *list = r; 80 : 81 228 : return 0; 82 0 : fail: 83 0 : if (r) { 84 0 : gnutls_free(r->data.data); 85 0 : gnutls_free(r); 86 : } 87 0 : gnutls_pkcs7_attrs_deinit(*list); 88 0 : return GNUTLS_E_MEMORY_ERROR; 89 : 90 : } 91 : 92 : /** 93 : * gnutls_pkcs7_get_attr: 94 : * @list: A list of existing attributes or %NULL for the first one 95 : * @idx: the index of the attribute to get 96 : * @oid: the OID of the attribute (read-only) 97 : * @data: the raw data of the attribute 98 : * @flags: zero or %GNUTLS_PKCS7_ATTR_ENCODE_OCTET_STRING 99 : * 100 : * This function will get a PKCS #7 attribute from the provided list. 101 : * The OID is a constant string, but data will be allocated and must be 102 : * deinitialized by the caller. 103 : * 104 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a 105 : * negative error value. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned 106 : * if there are no data in the current index. 107 : * 108 : * Since: 3.4.2 109 : **/ 110 : int 111 52 : gnutls_pkcs7_get_attr(gnutls_pkcs7_attrs_t list, unsigned idx, char **oid, 112 : gnutls_datum_t * data, unsigned flags) 113 : { 114 52 : unsigned i; 115 52 : gnutls_pkcs7_attrs_st *p = list; 116 52 : int ret; 117 : 118 132 : for (i = 0; i < idx; i++) { 119 91 : p = p->next; 120 91 : if (p == NULL) 121 : break; 122 : } 123 : 124 52 : if (p == NULL) 125 11 : return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); 126 : 127 41 : *oid = p->oid; 128 : 129 41 : if (flags & GNUTLS_PKCS7_ATTR_ENCODE_OCTET_STRING) { 130 3 : ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, 131 3 : p->data.data, p->data.size, 132 : data, 1); 133 : } else { 134 38 : ret = _gnutls_set_datum(data, p->data.data, p->data.size); 135 : } 136 41 : if (ret < 0) 137 0 : return gnutls_assert_val(ret); 138 : 139 : return 0; 140 : } 141 : 142 : /** 143 : * gnutls_pkcs7_attrs_deinit: 144 : * @list: A list of existing attributes 145 : * 146 : * This function will clear a PKCS #7 attribute list. 147 : * 148 : * Since: 3.4.2 149 : **/ 150 3176 : void gnutls_pkcs7_attrs_deinit(gnutls_pkcs7_attrs_t list) 151 : { 152 3176 : gnutls_pkcs7_attrs_st *r = list, *next; 153 : 154 3404 : while (r) { 155 228 : next = r->next; 156 : 157 228 : gnutls_free(r->data.data); 158 228 : gnutls_free(r->oid); 159 228 : gnutls_free(r); 160 228 : r = next; 161 : } 162 3176 : }