OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
pmeth_fn.c
Go to the documentation of this file.
1 /* pmeth_fn.c */
2 /* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
3  * project 2006.
4  */
5 /* ====================================================================
6  * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  * software must display the following acknowledgment:
22  * "This product includes software developed by the OpenSSL Project
23  * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  * endorse or promote products derived from this software without
27  * prior written permission. For written permission, please contact
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  * nor may "OpenSSL" appear in their names without prior written
32  * permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  * acknowledgment:
36  * "This product includes software developed by the OpenSSL Project
37  * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * ([email protected]). This product includes software written by Tim
55  * Hudson ([email protected]).
56  *
57  */
58 
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include "cryptlib.h"
62 #include <openssl/objects.h>
63 #include <openssl/evp.h>
64 #include "evp_locl.h"
65 
66 #define M_check_autoarg(ctx, arg, arglen, err) \
67  if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
68  { \
69  size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
70  if (!arg) \
71  { \
72  *arglen = pksize; \
73  return 1; \
74  } \
75  else if (*arglen < pksize) \
76  { \
77  EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
78  return 0; \
79  } \
80  }
81 
83  {
84  int ret;
85  if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
86  {
89  return -2;
90  }
92  if (!ctx->pmeth->sign_init)
93  return 1;
94  ret = ctx->pmeth->sign_init(ctx);
95  if (ret <= 0)
97  return ret;
98  }
99 
101  unsigned char *sig, size_t *siglen,
102  const unsigned char *tbs, size_t tbslen)
103  {
104  if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
105  {
108  return -2;
109  }
110  if (ctx->operation != EVP_PKEY_OP_SIGN)
111  {
113  return -1;
114  }
115  M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
116  return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
117  }
118 
120  {
121  int ret;
122  if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
123  {
126  return -2;
127  }
129  if (!ctx->pmeth->verify_init)
130  return 1;
131  ret = ctx->pmeth->verify_init(ctx);
132  if (ret <= 0)
134  return ret;
135  }
136 
138  const unsigned char *sig, size_t siglen,
139  const unsigned char *tbs, size_t tbslen)
140  {
141  if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
142  {
145  return -2;
146  }
147  if (ctx->operation != EVP_PKEY_OP_VERIFY)
148  {
150  return -1;
151  }
152  return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
153  }
154 
156  {
157  int ret;
158  if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
159  {
162  return -2;
163  }
165  if (!ctx->pmeth->verify_recover_init)
166  return 1;
167  ret = ctx->pmeth->verify_recover_init(ctx);
168  if (ret <= 0)
170  return ret;
171  }
172 
174  unsigned char *rout, size_t *routlen,
175  const unsigned char *sig, size_t siglen)
176  {
177  if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
178  {
181  return -2;
182  }
184  {
186  return -1;
187  }
189  return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
190  }
191 
193  {
194  int ret;
195  if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
196  {
199  return -2;
200  }
202  if (!ctx->pmeth->encrypt_init)
203  return 1;
204  ret = ctx->pmeth->encrypt_init(ctx);
205  if (ret <= 0)
207  return ret;
208  }
209 
211  unsigned char *out, size_t *outlen,
212  const unsigned char *in, size_t inlen)
213  {
214  if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
215  {
218  return -2;
219  }
220  if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
221  {
223  return -1;
224  }
225  M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
226  return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
227  }
228 
230  {
231  int ret;
232  if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
233  {
236  return -2;
237  }
239  if (!ctx->pmeth->decrypt_init)
240  return 1;
241  ret = ctx->pmeth->decrypt_init(ctx);
242  if (ret <= 0)
244  return ret;
245  }
246 
248  unsigned char *out, size_t *outlen,
249  const unsigned char *in, size_t inlen)
250  {
251  if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
252  {
255  return -2;
256  }
257  if (ctx->operation != EVP_PKEY_OP_DECRYPT)
258  {
260  return -1;
261  }
262  M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
263  return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
264  }
265 
266 
268  {
269  int ret;
270  if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
271  {
274  return -2;
275  }
277  if (!ctx->pmeth->derive_init)
278  return 1;
279  ret = ctx->pmeth->derive_init(ctx);
280  if (ret <= 0)
282  return ret;
283  }
284 
286  {
287  int ret;
288  if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
289  {
292  return -2;
293  }
295  {
298  return -1;
299  }
300 
301  ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
302 
303  if (ret <= 0)
304  return ret;
305 
306  if (ret == 2)
307  return 1;
308 
309  if (!ctx->pkey)
310  {
312  return -1;
313  }
314 
315  if (ctx->pkey->type != peer->type)
316  {
319  return -1;
320  }
321 
322  /* [email protected]: For clarity. The error is if parameters in peer are
323  * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
324  * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
325  * (different key types) is impossible here because it is checked earlier.
326  * -2 is OK for us here, as well as 1, so we can check for 0 only. */
327  if (!EVP_PKEY_missing_parameters(peer) &&
328  !EVP_PKEY_cmp_parameters(ctx->pkey, peer))
329  {
332  return -1;
333  }
334 
335  if (ctx->peerkey)
336  EVP_PKEY_free(ctx->peerkey);
337  ctx->peerkey = peer;
338 
339  ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
340 
341  if (ret <= 0)
342  {
343  ctx->peerkey = NULL;
344  return ret;
345  }
346 
348  return 1;
349  }
350 
351 
352 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
353  {
354  if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
355  {
358  return -2;
359  }
360  if (ctx->operation != EVP_PKEY_OP_DERIVE)
361  {
363  return -1;
364  }
365  M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
366  return ctx->pmeth->derive(ctx, key, pkeylen);
367  }
368