/* $Id: sfscrypt.h,v 1.17 2002/10/23 22:01:54 max Exp $ */ /* * * Copyright (C) 2002 David Mazieres * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ // SFSCRYPT // // This library servers as an abstract interface between specific // cryptographic implementations and the generic XDR implementations // of keys, ciphertexts, and signatures. // // XXX - a lot of functions should be inlined.... if we can get the compiler // to agree with that.. #ifndef _SFSMISC_SFSCRYPT_H #define _SFSMISC_SFSCRYPT_H 1 #include "crypt.h" #include "rabin.h" #include "serial.h" #include "sfs_prot.h" #include "sfsauth_prot.h" #include "sfsagent.h" #include "sfsconnect.h" #include "sfsmisc.h" #define SFS_ENCRYPT (1 << 0) #define SFS_VERIFY (1 << 1) #define SFS_DECRYPT (1 << 2) #define SFS_SIGN (1 << 3) class sfspub { public: sfspub (sfs_keytype kt, u_char o = 0, const str &k = NULL) : keylabel (k), ktype (kt), opts (o) {} virtual ~sfspub () {} sfs_keytype get_type () const { return ktype; } // Should be implemented by child classes virtual bool export_pubkey (sfs_pubkey2 *k) const = 0; virtual bool export_pubkey (strbuf &sb, bool prefix = true) const = 0; virtual bool check_keysize (str *s = NULL) const = 0; virtual bool encrypt (sfs_ctext2 *ct, const str &msg) const { return false; } virtual bool verify (const sfs_sig2 &sig, const str &msg, str *e = NULL) const { return false; } // These have reasonable default behavior virtual bool operator== (const str &s) const; virtual bool operator== (const sfspub &p) const; virtual bool operator== (const sfs_pubkey2 &pk) const; virtual bool operator== (const sfsauth_keyhalf &kh) const { return false; } virtual void set_username (const str &s) {} virtual void set_hostname (const str &s) {} virtual str get_hostname () const { return NULL; } virtual bool is_proac () const { return false; } // Legacy Code -- To be Phased out virtual bool is_v2 () const { return true; } virtual bool export_pubkey (sfs_pubkey *k) const { return false; } virtual bool encrypt (sfs_ctext *ct, const str &msg) const { return false; } virtual bool verify_r (const bigint &n, size_t len, str &msg, str *e = NULL) const { return false; } bool check_opts () const { return (!get_opt (get_bad_opts ())); } bool get_pubkey_hash (sfs_hash *h) const ; str get_pubkey_hash () const; const str keylabel; protected: bool verify_init (const sfs_sig2 &sig, const str &msg, str *e) const; virtual u_char get_bad_opts () const { return (SFS_DECRYPT | SFS_SIGN); } bool get_opt (u_char o) const { return (opts & o); } const sfs_keytype ktype; const u_char opts; }; class sfspriv : virtual public sfspub { public: sfspriv (sfs_keytype kt, u_char o = 0, const str &k = NULL) : sfspub (kt, o, k) {} virtual ~sfspriv () {} // The Following 4 functions should be implemented by child classes virtual bool export_privkey (str *s) const = 0; virtual bool get_privkey_hash (u_int8_t *buf, const sfs_hash &hostid) const = 0; virtual bool decrypt (const sfs_ctext2 &ct, str *msg) const = 0; virtual bool sign (sfs_sig2 *sig, const str &msg) = 0; // Asynchronous version ; reasonable default is given virtual void sign (const sfsauth2_sigreq &sr, sfs_authinfo ainfo, cbsign cb); // Legacy Code -- to be phased out virtual bool decrypt (const sfs_ctext &ct, str *msg) const { return false; } virtual bool sign_r (sfs_sig *sig, const str &msg) const { return false; } // Implemented in terms of export_privkey (str *s) virtual bool export_privkey (str *s, const str &kn, str pwd, u_int cost) const; virtual bool export_privkey (str *s, const eksblowfish *eksb) const; bool export_privkey (str *s, const str &salt, const str &ske, const str &kn) const; virtual bool export_keyhalf (sfsauth_keyhalf *, bool *) const ; virtual bool export_privkey (sfs_privkey2_clear *k) const { return false; } virtual str get_desc () const { return ("generic private key"); } // Initialize a key by signing a null request void init (cbs cb); void initcb (cbs cb, str err, ptr sig); // Functions needed for abstraction of multi-party signatures virtual ptr regen () const { return NULL; } virtual ptr update () const { return NULL; } virtual ptr wholekey () const { return NULL; } virtual bool get_coninfo (ptr *c, str *h) const { return false; } protected: u_char get_bad_modes () { return 0; } void signcb (str *errp, sfs_sig2 *sigp, str err, ptr sig); }; class sfsca { // SFS Crypt Allocator public: sfsca () : ktype (SFS_NOKEY) {} sfsca (sfs_keytype x, const str &s) : ktype (x), skey (s) {} // These 6 functions should be implemented by child classes virtual ptr alloc (const sfs_pubkey2 &pk, u_char o = 0) const = 0; virtual ptr alloc (const str &s, u_char o = 0) const = 0; virtual ptr alloc (const sfs_privkey2_clear &pk, u_char o = 0) const = 0; virtual ptr alloc (const str &raw, ptr s, u_char o = 0) const = 0; virtual ptr gen (u_int nbits, u_char o = 0) const { return NULL; } virtual const sfs_keytype *get_private_keytypes (u_int *n) const { return NULL; } // Legacy Code virtual ptr alloc (const sfs_pubkey &pk, u_char o = 0) const { return NULL; } virtual ~sfsca () {} ihash_entry hlinks; ihash_entry hlinkx; sfs_keytype ktype; str skey; }; class sfs_rabin_pub : virtual public sfspub { public: sfs_rabin_pub (ref k, u_char o = 0) : sfspub (SFS_RABIN, o, "rabin"), pubk (k) {} bool verify (const sfs_sig2 &sig, const str &msg, str *e = NULL) const; bool export_pubkey (sfs_pubkey2 *k) const; bool export_pubkey (strbuf &b, bool prefix = true) const; bool check_keysize (str *s = NULL) const; bool encrypt (sfs_ctext2 *ct, const str &msg) const; static bool check_keysize (size_t nbits, str *s = NULL); // Legacy Code bool verify_r (const bigint &n, size_t len, str &msg, str *e = NULL) const; bool export_pubkey (sfs_pubkey *k) const; bool encrypt (sfs_ctext *ct, const str &msg) const; bool is_v2 () const { return false; } private: ref pubk; }; class sfs_rabin_priv : public sfs_rabin_pub, public sfspriv { public: sfs_rabin_priv (ref k, u_char o = 0) : sfspub (SFS_RABIN, o, "rabin"), sfs_rabin_pub (k), sfspriv (SFS_RABIN, o, "rabin"), privk (k) {} bool sign (sfs_sig2 *s, const str &msg); bool export_privkey (sfs_privkey2_clear *k) const; bool export_privkey (str *s) const; bool decrypt (const sfs_ctext2 &ct, str *msg) const; bool get_privkey_hash (u_int8_t *buf, const sfs_hash &hostid) const; // Legacy Code bool sign_r (sfs_sig *sig, const str &msg) const; bool decrypt (const sfs_ctext &ct, str *msg) const; str get_desc () const { strbuf b; export_pubkey (b); return b;} private: ref privk; }; class sfs_rabin_alloc : public sfsca { public: sfs_rabin_alloc (sfs_keytype kt = SFS_RABIN, const str &s = "rabin") : sfsca (kt, s) {} ptr alloc (const sfs_privkey2_clear &pk, u_char o = 0) const; ptr alloc (const sfs_pubkey2 &pk, u_char o = 0) const; ptr alloc (const str &s, u_char o = 0) const; ptr gen (u_int nbits, u_char o = 0) const; ptr alloc (const str &raw, ptr c, u_char o = 0) const; // Old protocol ptr alloc (const sfs_pubkey &pk, u_char o = 0) const; }; class sfscrypt_t { public: sfscrypt_t (); ptr alloc (const sfs_privkey2_clear &pk, u_char o = 0) const; ptr alloc (const str &ske, str *kn, str *pwd, u_int *cost, u_char o = 0) const; ptr alloc (const sfs_pubkey2 &pk, u_char o = 0) const; ptr alloc (const str &s, u_char o = 0) const; ptr alloc (sfs_keytype xt, const str &esk, const eksblowfish *eksb, ptr s = NULL, u_char o = 0) const; ptr gen (sfs_keytype xt, u_int nbits, u_char o = 0) const; ptr alloc_priv (const str &sk, u_char o = 0) const; ptr alloc_from_priv (const str &sk) const; // Legacy Code ptr alloc (const sfs_pubkey &pk, u_char o = 0) const; bool verify (const sfs_pubkey2 &pk, const sfs_sig2 &sig, const str &msg, str *e = NULL) const; void add (sfsca *c) { if (c->skey.len ()) { strtab.insert (c); } if (c->ktype && !xttab[c->ktype]) { xttab.insert (c); } } private: ptr alloc (sfs_keytype xt, const str &pk, u_char o = 0) const; bool parse (const str &raw, sfs_keytype *xt, str *salt, str *ske, str *pk, str *kn) const; bool verify_sk (ref k, sfs_keytype xt, const str &pk) const ; ihash strtab; ihash xttab; }; #define SALTBITS SK_RABIN_SALTBITS extern sfscrypt_t sfscrypt; str sk_decrypt (const str &epk, const eksblowfish *eksb); str sk_encrypt (const str &pk, const eksblowfish *eksb); str timestr (); template str xdr2str_pad (const T &t, bool scrub = false, u_int align = 8) { xdrsuio x (XDR_ENCODE, scrub); XDR *xp = &x; if (!rpc_traverse (xp, const_cast (t))) return NULL; while (x.uio ()->resid () & (align >> 1)) if (!xdr_putint (&x, 0)) return NULL; mstr m (x.uio ()->resid ()); x.uio ()->copyout (m); if (scrub) return str2wstr (m); return m; } #endif /* _SFSMISC_SFSCRYPT_H */