summaryrefslogtreecommitdiff
path: root/ssh-ecdsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-ecdsa.c')
-rw-r--r--ssh-ecdsa.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 766338941..10ad9da60 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ecdsa.c,v 1.6 2013/05/17 00:13:14 djm Exp $ */ 1/* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -42,27 +42,34 @@
42#include "compat.h" 42#include "compat.h"
43#include "log.h" 43#include "log.h"
44#include "key.h" 44#include "key.h"
45#include "digest.h"
45 46
46int 47int
47ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, 48ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
48 const u_char *data, u_int datalen) 49 const u_char *data, u_int datalen)
49{ 50{
50 ECDSA_SIG *sig; 51 ECDSA_SIG *sig;
51 const EVP_MD *evp_md; 52 int hash_alg;
52 EVP_MD_CTX md; 53 u_char digest[SSH_DIGEST_MAX_LENGTH];
53 u_char digest[EVP_MAX_MD_SIZE];
54 u_int len, dlen; 54 u_int len, dlen;
55 Buffer b, bb; 55 Buffer b, bb;
56 56
57 if (key == NULL || key->ecdsa == NULL || 57 if (key == NULL || key_type_plain(key->type) != KEY_ECDSA ||
58 (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { 58 key->ecdsa == NULL) {
59 error("%s: no ECDSA key", __func__); 59 error("%s: no ECDSA key", __func__);
60 return -1; 60 return -1;
61 } 61 }
62 evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); 62
63 EVP_DigestInit(&md, evp_md); 63 hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
64 EVP_DigestUpdate(&md, data, datalen); 64 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
65 EVP_DigestFinal(&md, digest, &dlen); 65 error("%s: bad hash algorithm %d", __func__, hash_alg);
66 return -1;
67 }
68 if (ssh_digest_memory(hash_alg, data, datalen,
69 digest, sizeof(digest)) != 0) {
70 error("%s: digest_memory failed", __func__);
71 return -1;
72 }
66 73
67 sig = ECDSA_do_sign(digest, dlen, key->ecdsa); 74 sig = ECDSA_do_sign(digest, dlen, key->ecdsa);
68 memset(digest, 'd', sizeof(digest)); 75 memset(digest, 'd', sizeof(digest));
@@ -97,20 +104,18 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
97 const u_char *data, u_int datalen) 104 const u_char *data, u_int datalen)
98{ 105{
99 ECDSA_SIG *sig; 106 ECDSA_SIG *sig;
100 const EVP_MD *evp_md; 107 int hash_alg;
101 EVP_MD_CTX md; 108 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
102 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
103 u_int len, dlen; 109 u_int len, dlen;
104 int rlen, ret; 110 int rlen, ret;
105 Buffer b, bb; 111 Buffer b, bb;
106 char *ktype; 112 char *ktype;
107 113
108 if (key == NULL || key->ecdsa == NULL || 114 if (key == NULL || key_type_plain(key->type) != KEY_ECDSA ||
109 (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { 115 key->ecdsa == NULL) {
110 error("%s: no ECDSA key", __func__); 116 error("%s: no ECDSA key", __func__);
111 return -1; 117 return -1;
112 } 118 }
113 evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);
114 119
115 /* fetch signature */ 120 /* fetch signature */
116 buffer_init(&b); 121 buffer_init(&b);
@@ -152,9 +157,16 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
152 free(sigblob); 157 free(sigblob);
153 158
154 /* hash the data */ 159 /* hash the data */
155 EVP_DigestInit(&md, evp_md); 160 hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
156 EVP_DigestUpdate(&md, data, datalen); 161 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
157 EVP_DigestFinal(&md, digest, &dlen); 162 error("%s: bad hash algorithm %d", __func__, hash_alg);
163 return -1;
164 }
165 if (ssh_digest_memory(hash_alg, data, datalen,
166 digest, sizeof(digest)) != 0) {
167 error("%s: digest_memory failed", __func__);
168 return -1;
169 }
158 170
159 ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); 171 ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
160 memset(digest, 'd', sizeof(digest)); 172 memset(digest, 'd', sizeof(digest));