00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef CRYPTO_H
00011 #define CRYPTO_H CRYPTO_H
00012 #ifdef HAVE_NO_CRYPTO
00013 #error "including crypto"
00014 #endif
00015
00016 #include <vector>
00017 #include <gcrypt.h>
00018
00019 #include "rsa.h"
00020 #include "formatStrings.h"
00021 #include "readTypes.h"
00022 #include "reporter.h"
00023 #include "helper.h"
00024 #include "slurpedfile.h"
00025 #include "typedefs.h"
00026
00027 bool checkSHA1match(const unsigned char* text, int textlength, const unsigned char* hash){
00028 std::vector<unsigned char> buffer(20);
00029 gcry_md_hash_buffer(GCRY_MD_SHA1, &buffer[0], text, textlength);
00030 bool cmp = true;
00031 for(int j = 0; cmp && j < 20; ++j){
00032 cmp = (hash[j] == buffer[j]);
00033 }
00034 return cmp;
00035 }
00036
00037
00038 class CAid{
00039 public:
00040 int numNation;
00041 string alphaNation;
00042 int serialNumber;
00043 int additionalCoding;
00044 int identifier;
00045 bool operator==(const CAid& other) const{
00046 return numNation == other.numNation && alphaNation == other.alphaNation && serialNumber == other.serialNumber && additionalCoding == other.additionalCoding && identifier == other.identifier;
00047 }
00048 bool operator!=(const CAid& other) const{ return !operator==(other); }
00049 CAid(iter start) :
00050 numNation(start[0]),
00051 alphaNation(fixedString(start + 1, 3)),
00052 serialNumber(start[4]),
00053 additionalCoding(BEInt16(start + 5)),
00054 identifier(start[7])
00055 {}
00056 friend reporter& operator<<(reporter& o, const CAid& p){
00057 o("nationNumeric", nationNumeric(p.numNation));
00058 o("nationAlpha", p.alphaNation);
00059 o("keySerialNumber", p.serialNumber);
00060 o("additionalInfo", p.additionalCoding);
00061 o("caIdentifier", p.identifier);
00062 return o;
00063 }
00064 };
00065
00066 class verifiedcert{
00067 public:
00068 iter start;
00069 CAid car;
00070 bool verified;
00071 rsa key;
00072 typedef shared_ptr<verifiedcert> ptr;
00073 verifiedcert(iter start_) : start(start_), car(start + 186), verified(false) {}
00074 bool verify(const string& filename){
00075 slurpedfile rawkey = slurp(filename);
00076 CAid rawkey_ca(rawkey.begin());
00077 if(rawkey_ca != car){
00078 std::cerr << "Attempting to use wrong ca certificate.";
00079 return false;
00080 }
00081 return verify(rsa(&rawkey[8], 128, &rawkey[136], 8));
00082 }
00083 bool verify(const verifiedcert& other){
00084 return other.verified && verify(other.key);
00085 }
00086 bool verify(const rsa& extkey){
00087 std::vector<unsigned char> buffer = extkey.perform(&start[0], 128);
00088 unsigned char cdash[164];
00089 copy(&buffer[1], &cdash[0], 106);
00090 copy(&start[128], &cdash[106], 58);
00091 if(!checkSHA1match(cdash, 164, &buffer[107])){
00092 std::cout << "Certificate is invalid.\n";
00093 return false;
00094 }
00095 key = rsa(&cdash[28],128,&cdash[156],8);
00096 verified = true;
00097 return true;
00098 }
00099 friend reporter& operator<<(reporter& o, const verifiedcert& p){
00100 return o << p.car;
00101 }
00102 };
00103
00104 bool CheckSignature(const iter& data, int length, const iter& signature, int siglength, const rsa& key){
00105 std::vector<unsigned char> decryptedsig = key.perform(&signature[0],siglength);
00106 bool valid = checkSHA1match(&data[0], length,&decryptedsig[107]);
00107 const unsigned char der[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
00108 valid = valid && compare(&decryptedsig[92],der,15);
00109 for(int j = 1; j < 91; ++j) if(decryptedsig[j] != 0xff) valid = false;
00110
00111
00112 if(!valid){
00113 std::cerr << "\nsignature check failed ";
00114 }
00115 return valid;
00116 }
00117
00118 #endif