-/***************************************************************************
- *
- * Part II Project, "A secure, private IP network"
- * Stephen Early <sde1000@cam.ac.uk>
- *
- *
- * $RCSfile: rsa.c,v $
- *
- * Description: RSA signature making and checking functions
- *
- * Copyright: (C) Stephen Early 1995
- *
- * $Revision: 1.1 $
- *
- * $Date: 1996/05/16 18:40:14 $
- *
- * $State: Exp $
- *
- ***************************************************************************/
-
-/* $Log: rsa.c,v $
- * Revision 1.1 1996/05/16 18:40:14 sde1000
- * Initial revision
- *
- */
-
#include <stdio.h>
#include <gmp.h>
#include "secnet.h"
msize=mpz_sizeinbase(&st->n, 16);
+ if (datalen*2+4>=msize) {
+ fatal("rsa_sign: message too big");
+ }
+
strcpy(buff,"0001");
for (i=0; i<datalen; i++) {
buff[5+i*2]=hexchars[data[i]&0xf];
}
buff[4+datalen*2]=0;
-
+
for (i=datalen*2+4; i<msize; i++)
buff[i]='f';
return new_closure(&st->cl);
}
-static uint32_t keyfile_get_int(FILE *f)
+static uint32_t keyfile_get_int(struct cloc loc, FILE *f)
{
uint32_t r;
r=fgetc(f)<<24;
r|=fgetc(f)<<16;
r|=fgetc(f)<<8;
r|=fgetc(f);
+ cfgfile_postreadcheck(loc,f);
return r;
}
-static uint16_t keyfile_get_short(FILE *f)
+static uint16_t keyfile_get_short(struct cloc loc, FILE *f)
{
uint16_t r;
r=fgetc(f)<<8;
r|=fgetc(f);
+ cfgfile_postreadcheck(loc,f);
return r;
}
f=fopen(filename,"rb");
if (!f) {
- fatal_perror("rsa-private (%s:%d): cannot open file \"%s\"",
- loc.file,loc.line,filename);
+ if (just_check_config) {
+ Message(M_WARNING,"rsa-private (%s:%d): cannot open keyfile "
+ "\"%s\"; assuming it's valid while we check the "
+ "rest of the configuration\n",loc.file,loc.line,filename);
+ goto assume_valid;
+ } else {
+ fatal_perror("rsa-private (%s:%d): cannot open file \"%s\"",
+ loc.file,loc.line,filename);
+ }
}
/* Check that the ID string is correct */
length=strlen(AUTHFILE_ID_STRING)+1;
b=safe_malloc(length,"rsapriv_apply");
if (fread(b,length,1,f)!=1 || memcmp(b,AUTHFILE_ID_STRING,length)!=0) {
- cfgfatal(loc,"rsa-private","file \"%s\" is not a "
- "SSH1 private keyfile\n",filename);
+ cfgfatal_maybefile(f,loc,"rsa-private","failed to read magic ID"
+ " string from SSH1 private keyfile \"%s\"\n",
+ filename);
}
free(b);
cipher_type=fgetc(f);
- keyfile_get_int(f); /* "Reserved data" */
+ keyfile_get_int(loc,f); /* "Reserved data" */
if (cipher_type != 0) {
cfgfatal(loc,"rsa-private","we don't support encrypted keyfiles\n");
}
/* Read the public key */
- keyfile_get_int(f); /* Not sure what this is */
- length=(keyfile_get_short(f)+7)/8;
+ keyfile_get_int(loc,f); /* Not sure what this is */
+ length=(keyfile_get_short(loc,f)+7)/8;
if (length>1024) {
cfgfatal(loc,"rsa-private","implausible length %ld for modulus\n",
length);
}
b=safe_malloc(length,"rsapriv_apply");
if (fread(b,length,1,f) != 1) {
- cfgfatal(loc,"rsa-private","error reading modulus\n");
+ cfgfatal_maybefile(f,loc,"rsa-private","error reading modulus");
}
mpz_init(&st->n);
read_mpbin(&st->n,b,length);
free(b);
- length=(keyfile_get_short(f)+7)/8;
+ length=(keyfile_get_short(loc,f)+7)/8;
if (length>1024) {
cfgfatal(loc,"rsa-private","implausible length %ld for e\n",length);
}
b=safe_malloc(length,"rsapriv_apply");
if (fread(b,length,1,f)!=1) {
- cfgfatal(loc,"rsa-private","error reading e\n");
+ cfgfatal_maybefile(f,loc,"rsa-private","error reading e\n");
}
mpz_init(&e);
read_mpbin(&e,b,length);
free(b);
- length=keyfile_get_int(f);
+ length=keyfile_get_int(loc,f);
if (length>1024) {
cfgfatal(loc,"rsa-private","implausibly long (%ld) key comment\n",
length);
}
c=safe_malloc(length+1,"rsapriv_apply");
if (fread(c,length,1,f)!=1) {
- cfgfatal(loc,"rsa-private","error reading key comment\n");
+ cfgfatal_maybefile(f,loc,"rsa-private","error reading key comment\n");
}
c[length]=0;
/* Check that the next two pairs of characters are identical - the
keyfile is not encrypted, so they should be */
- if (keyfile_get_short(f) != keyfile_get_short(f)) {
+
+ if (keyfile_get_short(loc,f) != keyfile_get_short(loc,f)) {
cfgfatal(loc,"rsa-private","corrupt keyfile\n");
}
/* Read d */
- length=(keyfile_get_short(f)+7)/8;
+ length=(keyfile_get_short(loc,f)+7)/8;
if (length>1024) {
cfgfatal(loc,"rsa-private","implausibly long (%ld) decryption key\n",
length);
}
b=safe_malloc(length,"rsapriv_apply");
if (fread(b,length,1,f)!=1) {
- cfgfatal(loc,"rsa-private","error reading decryption key\n");
+ cfgfatal_maybefile(f,loc,"rsa-private",
+ "error reading decryption key\n");
}
mpz_init(&st->d);
read_mpbin(&st->d,b,length);
/* Now do trial signature/check to make sure it's a real keypair:
sign the comment string! */
- mpz_init(&sig);
- mpz_init(&plain);
- mpz_init(&check);
- read_mpbin(&plain,c,strlen(c));
- mpz_powm(&sig, &plain, &st->d, &st->n);
- mpz_powm(&check, &sig, &e, &st->n);
- if (mpz_cmp(&plain,&check)!=0) {
- cfgfatal(loc,"rsa-private","file \"%s\" does not contain a "
- "valid RSA key!\n",filename);
+ i=list_elem(args,1);
+ if (i && i->type==t_bool && i->data.bool==False) {
+ Message(M_INFO,"rsa-private (%s:%d): skipping RSA key validity "
+ "check\n",loc.file,loc.line);
+ } else {
+ mpz_init(&sig);
+ mpz_init(&plain);
+ mpz_init(&check);
+ read_mpbin(&plain,c,strlen(c));
+ mpz_powm(&sig, &plain, &st->d, &st->n);
+ mpz_powm(&check, &sig, &e, &st->n);
+ if (mpz_cmp(&plain,&check)!=0) {
+ cfgfatal(loc,"rsa-private","file \"%s\" does not contain a "
+ "valid RSA key!\n",filename);
+ }
+ mpz_clear(&sig);
+ mpz_clear(&plain);
+ mpz_clear(&check);
}
- mpz_clear(&sig);
- mpz_clear(&plain);
- mpz_clear(&check);
free(c);
mpz_clear(&e);
+assume_valid:
return new_closure(&st->cl);
}