Annotation of src/usr.bin/ssh/ssh-rsa.c, Revision 1.1
1.1 ! markus 1: /*
! 2: * Copyright (c) 2000 Markus Friedl. All rights reserved.
! 3: *
! 4: * Redistribution and use in source and binary forms, with or without
! 5: * modification, are permitted provided that the following conditions
! 6: * are met:
! 7: * 1. Redistributions of source code must retain the above copyright
! 8: * notice, this list of conditions and the following disclaimer.
! 9: * 2. Redistributions in binary form must reproduce the above copyright
! 10: * notice, this list of conditions and the following disclaimer in the
! 11: * documentation and/or other materials provided with the distribution.
! 12: *
! 13: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 14: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 15: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 16: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 17: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 18: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 19: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 20: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 21: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 22: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 23: */
! 24:
! 25: #include "includes.h"
! 26: RCSID("$OpenBSD: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $");
! 27:
! 28: #include "ssh.h"
! 29: #include "xmalloc.h"
! 30: #include "buffer.h"
! 31: #include "bufaux.h"
! 32:
! 33: #include <openssl/evp.h>
! 34: #include <openssl/dsa.h>
! 35: #include <openssl/rsa.h>
! 36: #include <openssl/err.h>
! 37:
! 38: #include "key.h"
! 39:
! 40: #define INTBLOB_LEN 20
! 41: #define SIGBLOB_LEN (2*INTBLOB_LEN)
! 42:
! 43: /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
! 44: int
! 45: ssh_rsa_sign(
! 46: Key *key,
! 47: unsigned char **sigp, int *lenp,
! 48: unsigned char *data, int datalen)
! 49: {
! 50: EVP_MD *evp_md = EVP_sha1();
! 51: EVP_MD_CTX md;
! 52: unsigned char *digest, *sig, *ret;
! 53: unsigned int slen, dlen, len;
! 54: int ok;
! 55: Buffer b;
! 56:
! 57: if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
! 58: error("ssh_rsa_sign: no RSA key");
! 59: return -1;
! 60: }
! 61: slen = RSA_size(key->rsa);
! 62: sig = xmalloc(slen);
! 63:
! 64: dlen = evp_md->md_size;
! 65: digest = xmalloc(dlen);
! 66: EVP_DigestInit(&md, evp_md);
! 67: EVP_DigestUpdate(&md, data, datalen);
! 68: EVP_DigestFinal(&md, digest, NULL);
! 69:
! 70: ok = RSA_sign(NID_sha1, digest, dlen, sig, &len, key->rsa);
! 71: memset(digest, 'd', dlen);
! 72: xfree(digest);
! 73:
! 74: if (ok != 1) {
! 75: int ecode = ERR_get_error();
! 76: error("ssh_rsa_sign: RSA_sign failed: %s", ERR_error_string(ecode, NULL));
! 77: xfree(sig);
! 78: return -1;
! 79: }
! 80: if (len < slen) {
! 81: int diff = slen - len;
! 82: debug("slen %d > len %d", slen, len);
! 83: memmove(sig + diff, sig, len);
! 84: memset(sig, 0, diff);
! 85: } else if (len > slen) {
! 86: error("ssh_rsa_sign: slen %d slen2 %d", slen, len);
! 87: xfree(sig);
! 88: return -1;
! 89: }
! 90: /* encode signature */
! 91: buffer_init(&b);
! 92: buffer_put_cstring(&b, "ssh-rsa");
! 93: buffer_put_string(&b, sig, slen);
! 94: len = buffer_len(&b);
! 95: ret = xmalloc(len);
! 96: memcpy(ret, buffer_ptr(&b), len);
! 97: buffer_free(&b);
! 98: memset(sig, 's', slen);
! 99: xfree(sig);
! 100:
! 101: if (lenp != NULL)
! 102: *lenp = len;
! 103: if (sigp != NULL)
! 104: *sigp = ret;
! 105: debug2("ssh_rsa_sign: done");
! 106: return 0;
! 107: }
! 108:
! 109: int
! 110: ssh_rsa_verify(
! 111: Key *key,
! 112: unsigned char *signature, int signaturelen,
! 113: unsigned char *data, int datalen)
! 114: {
! 115: Buffer b;
! 116: EVP_MD *evp_md = EVP_sha1();
! 117: EVP_MD_CTX md;
! 118: char *ktype;
! 119: unsigned char *sigblob, *digest;
! 120: unsigned int len, dlen;
! 121: int rlen;
! 122: int ret;
! 123:
! 124: if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
! 125: error("ssh_rsa_verify: no RSA key");
! 126: return -1;
! 127: }
! 128: buffer_init(&b);
! 129: buffer_append(&b, (char *) signature, signaturelen);
! 130: ktype = buffer_get_string(&b, NULL);
! 131: if (strcmp("ssh-rsa", ktype) != 0) {
! 132: error("ssh_rsa_verify: cannot handle type %s", ktype);
! 133: buffer_free(&b);
! 134: xfree(ktype);
! 135: return -1;
! 136: }
! 137: xfree(ktype);
! 138: sigblob = (unsigned char *)buffer_get_string(&b, &len);
! 139: rlen = buffer_len(&b);
! 140: buffer_free(&b);
! 141: if(rlen != 0) {
! 142: error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
! 143: return -1;
! 144: }
! 145:
! 146: dlen = evp_md->md_size;
! 147: digest = xmalloc(dlen);
! 148: EVP_DigestInit(&md, evp_md);
! 149: EVP_DigestUpdate(&md, data, datalen);
! 150: EVP_DigestFinal(&md, digest, NULL);
! 151:
! 152: ret = RSA_verify(NID_sha1, digest, dlen, sigblob, len, key->rsa);
! 153: memset(digest, 'd', dlen);
! 154: xfree(digest);
! 155: memset(sigblob, 's', len);
! 156: xfree(sigblob);
! 157: if (ret == 0) {
! 158: int ecode = ERR_get_error();
! 159: error("ssh_rsa_verify: RSA_verify failed: %s", ERR_error_string(ecode, NULL));
! 160: }
! 161: debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
! 162: return ret;
! 163: }