1178825Sdfr/*
2233294Sstas * Copyright (c) 2006 - 2007 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
5178825Sdfr *
6233294Sstas * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7178825Sdfr *
8233294Sstas * Redistribution and use in source and binary forms, with or without
9233294Sstas * modification, are permitted provided that the following conditions
10233294Sstas * are met:
11178825Sdfr *
12233294Sstas * 1. Redistributions of source code must retain the above copyright
13233294Sstas *    notice, this list of conditions and the following disclaimer.
14178825Sdfr *
15233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
16233294Sstas *    notice, this list of conditions and the following disclaimer in the
17233294Sstas *    documentation and/or other materials provided with the distribution.
18178825Sdfr *
19233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
20233294Sstas *    may be used to endorse or promote products derived from this software
21233294Sstas *    without specific prior written permission.
22233294Sstas *
23233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33233294Sstas * SUCH DAMAGE.
34178825Sdfr */
35178825Sdfr
36178825Sdfr#include "hx_locl.h"
37178825Sdfr
38178825Sdfr/**
39178825Sdfr * @page page_peer Hx509 crypto selecting functions
40178825Sdfr *
41178825Sdfr * Peer info structures are used togeter with hx509_crypto_select() to
42178825Sdfr * select the best avaible crypto algorithm to use.
43178825Sdfr *
44178825Sdfr * See the library functions here: @ref hx509_peer
45178825Sdfr */
46178825Sdfr
47178825Sdfr/**
48178825Sdfr * Allocate a new peer info structure an init it to default values.
49178825Sdfr *
50178825Sdfr * @param context A hx509 context.
51178825Sdfr * @param peer return an allocated peer, free with hx509_peer_info_free().
52178825Sdfr *
53178825Sdfr * @return An hx509 error code, see hx509_get_error_string().
54178825Sdfr *
55178825Sdfr * @ingroup hx509_peer
56178825Sdfr */
57178825Sdfr
58178825Sdfrint
59178825Sdfrhx509_peer_info_alloc(hx509_context context, hx509_peer_info *peer)
60178825Sdfr{
61178825Sdfr    *peer = calloc(1, sizeof(**peer));
62178825Sdfr    if (*peer == NULL) {
63178825Sdfr	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
64178825Sdfr	return ENOMEM;
65178825Sdfr    }
66178825Sdfr    return 0;
67178825Sdfr}
68178825Sdfr
69178825Sdfr
70178825Sdfrstatic void
71178825Sdfrfree_cms_alg(hx509_peer_info peer)
72178825Sdfr{
73178825Sdfr    if (peer->val) {
74178825Sdfr	size_t i;
75178825Sdfr	for (i = 0; i < peer->len; i++)
76178825Sdfr	    free_AlgorithmIdentifier(&peer->val[i]);
77178825Sdfr	free(peer->val);
78178825Sdfr	peer->val = NULL;
79178825Sdfr	peer->len = 0;
80178825Sdfr    }
81178825Sdfr}
82178825Sdfr
83178825Sdfr/**
84178825Sdfr * Free a peer info structure.
85178825Sdfr *
86178825Sdfr * @param peer peer info to be freed.
87178825Sdfr *
88178825Sdfr * @ingroup hx509_peer
89178825Sdfr */
90178825Sdfr
91178825Sdfrvoid
92178825Sdfrhx509_peer_info_free(hx509_peer_info peer)
93178825Sdfr{
94178825Sdfr    if (peer == NULL)
95178825Sdfr	return;
96178825Sdfr    if (peer->cert)
97178825Sdfr	hx509_cert_free(peer->cert);
98178825Sdfr    free_cms_alg(peer);
99178825Sdfr    memset(peer, 0, sizeof(*peer));
100178825Sdfr    free(peer);
101178825Sdfr}
102178825Sdfr
103178825Sdfr/**
104178825Sdfr * Set the certificate that remote peer is using.
105178825Sdfr *
106178825Sdfr * @param peer peer info to update
107178825Sdfr * @param cert cerificate of the remote peer.
108178825Sdfr *
109178825Sdfr * @return An hx509 error code, see hx509_get_error_string().
110178825Sdfr *
111178825Sdfr * @ingroup hx509_peer
112178825Sdfr */
113178825Sdfr
114178825Sdfrint
115178825Sdfrhx509_peer_info_set_cert(hx509_peer_info peer,
116178825Sdfr			 hx509_cert cert)
117178825Sdfr{
118178825Sdfr    if (peer->cert)
119178825Sdfr	hx509_cert_free(peer->cert);
120178825Sdfr    peer->cert = hx509_cert_ref(cert);
121178825Sdfr    return 0;
122178825Sdfr}
123178825Sdfr
124178825Sdfr/**
125233294Sstas * Add an additional algorithm that the peer supports.
126233294Sstas *
127233294Sstas * @param context A hx509 context.
128233294Sstas * @param peer the peer to set the new algorithms for
129233294Sstas * @param val an AlgorithmsIdentier to add
130233294Sstas *
131233294Sstas * @return An hx509 error code, see hx509_get_error_string().
132233294Sstas *
133233294Sstas * @ingroup hx509_peer
134233294Sstas */
135233294Sstas
136233294Sstasint
137233294Sstashx509_peer_info_add_cms_alg(hx509_context context,
138233294Sstas			    hx509_peer_info peer,
139233294Sstas			    const AlgorithmIdentifier *val)
140233294Sstas{
141233294Sstas    void *ptr;
142233294Sstas    int ret;
143233294Sstas
144233294Sstas    ptr = realloc(peer->val, sizeof(peer->val[0]) * (peer->len + 1));
145233294Sstas    if (ptr == NULL) {
146233294Sstas	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
147233294Sstas	return ENOMEM;
148233294Sstas    }
149233294Sstas    peer->val = ptr;
150233294Sstas    ret = copy_AlgorithmIdentifier(val, &peer->val[peer->len]);
151233294Sstas    if (ret == 0)
152233294Sstas	peer->len += 1;
153233294Sstas    else
154233294Sstas	hx509_set_error_string(context, 0, ret, "out of memory");
155233294Sstas    return ret;
156233294Sstas}
157233294Sstas
158233294Sstas/**
159178825Sdfr * Set the algorithms that the peer supports.
160178825Sdfr *
161178825Sdfr * @param context A hx509 context.
162178825Sdfr * @param peer the peer to set the new algorithms for
163178825Sdfr * @param val array of supported AlgorithmsIdentiers
164178825Sdfr * @param len length of array val.
165178825Sdfr *
166178825Sdfr * @return An hx509 error code, see hx509_get_error_string().
167178825Sdfr *
168178825Sdfr * @ingroup hx509_peer
169178825Sdfr */
170178825Sdfr
171178825Sdfrint
172178825Sdfrhx509_peer_info_set_cms_algs(hx509_context context,
173178825Sdfr			     hx509_peer_info peer,
174178825Sdfr			     const AlgorithmIdentifier *val,
175178825Sdfr			     size_t len)
176178825Sdfr{
177178825Sdfr    size_t i;
178178825Sdfr
179178825Sdfr    free_cms_alg(peer);
180178825Sdfr
181178825Sdfr    peer->val = calloc(len, sizeof(*peer->val));
182178825Sdfr    if (peer->val == NULL) {
183178825Sdfr	peer->len = 0;
184178825Sdfr	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
185178825Sdfr	return ENOMEM;
186178825Sdfr    }
187178825Sdfr    peer->len = len;
188178825Sdfr    for (i = 0; i < len; i++) {
189178825Sdfr	int ret;
190178825Sdfr	ret = copy_AlgorithmIdentifier(&val[i], &peer->val[i]);
191178825Sdfr	if (ret) {
192178825Sdfr	    hx509_clear_error_string(context);
193178825Sdfr	    free_cms_alg(peer);
194178825Sdfr	    return ret;
195178825Sdfr	}
196178825Sdfr    }
197178825Sdfr    return 0;
198178825Sdfr}
199178825Sdfr
200178825Sdfr#if 0
201178825Sdfr
202178825Sdfr/*
203178825Sdfr * S/MIME
204178825Sdfr */
205178825Sdfr
206178825Sdfrint
207178825Sdfrhx509_peer_info_parse_smime(hx509_peer_info peer,
208178825Sdfr			    const heim_octet_string *data)
209178825Sdfr{
210178825Sdfr    return 0;
211178825Sdfr}
212178825Sdfr
213178825Sdfrint
214178825Sdfrhx509_peer_info_unparse_smime(hx509_peer_info peer,
215178825Sdfr			      heim_octet_string *data)
216178825Sdfr{
217178825Sdfr    return 0;
218178825Sdfr}
219178825Sdfr
220178825Sdfr/*
221178825Sdfr * For storing hx509_peer_info to be able to cache them.
222178825Sdfr */
223178825Sdfr
224178825Sdfrint
225178825Sdfrhx509_peer_info_parse(hx509_peer_info peer,
226178825Sdfr		      const heim_octet_string *data)
227178825Sdfr{
228178825Sdfr    return 0;
229178825Sdfr}
230178825Sdfr
231178825Sdfrint
232178825Sdfrhx509_peer_info_unparse(hx509_peer_info peer,
233178825Sdfr			heim_octet_string *data)
234178825Sdfr{
235178825Sdfr    return 0;
236178825Sdfr}
237178825Sdfr#endif
238