static bool DecodeFromFile(const char* filename, RSA::PrivateKey& key) { try { ByteQueue queue; FileSource file(filename, true); file.TransferTo(queue); queue.MessageEnd(); key.BERDecodePrivateKey(queue, false, queue.MaxRetrievable()); return key.Validate(rng, 3); } catch (...) { return false; } }
void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target) { std::string s1 = GetRequiredDatum(data, name), s2; while (!s1.empty()) { while (s1[0] == ' ') { s1 = s1.substr(1); if (s1.empty()) return; //avoid invalid read if s1 is empty } int repeat = 1; if (s1[0] == 'r') { repeat = atoi(s1.c_str()+1); s1 = s1.substr(s1.find(' ')+1); } s2 = ""; // MSVC 6 doesn't have clear(); if (s1[0] == '\"') { s2 = s1.substr(1, s1.find('\"', 1)-1); s1 = s1.substr(s2.length() + 2); } else if (s1.substr(0, 2) == "0x") { StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); } else { StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); } ByteQueue q; while (repeat--) { q.Put((const byte *)s2.data(), s2.size()); if (q.MaxRetrievable() > 4*1024 || repeat == 0) q.TransferTo(target); } } }
extern "C" int rsa_pss_sign(const char *key_file, const unsigned char *msg, int len, unsigned char *sig_buf, unsigned char *modulus_buf) { try { AutoSeededRandomPool rng; FileSource file(key_file, true); RSA::PrivateKey key; ByteQueue bq; // Load the key file.TransferTo(bq); bq.MessageEnd(); key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable()); // Write the modulus Integer mod = key.GetModulus(); // error check if (mod.ByteCount() != RCM_RSA_MODULUS_SIZE) throw std::length_error("incorrect rsa key modulus length"); for (int i = 0; i < mod.ByteCount(); i++) modulus_buf[i] = mod.GetByte(i); // Sign the message RSASS<PSS, SHA256>::Signer signer(key); size_t length = signer.MaxSignatureLength(); SecByteBlock signature(length); length = signer.SignMessage(rng, msg, len, signature); // Copy in reverse order for (int i = 0; i < length; i++) sig_buf[length - i - 1] = signature[i]; } catch(const CryptoPP::Exception& e) { cerr << e.what() << endl; return 1; } catch(std::length_error& le) { cerr << "Error: " << le.what() << endl; return 1; } return 0; }
extern "C" int rsa_pss_sign_file(const char *key_file, const char *msg_file, unsigned char *sig_buf) { try { AutoSeededRandomPool rng; FileSource file(key_file, true); RSA::PrivateKey key; ByteQueue bq; // Load the key file.TransferTo(bq); bq.MessageEnd(); key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable()); // Sign the message RSASS<PSS, SHA256>::Signer signer(key); string signature; FileSource src(msg_file, true, new SignerFilter(rng, signer, new StringSink(signature))); int length = signature.length(); // error check if (length != RCM_RSA_SIG_SIZE) throw std::length_error("incorrect rsa key length"); // Copy in reverse order for (int i = 0; i < length; i++) sig_buf[length - i - 1] = signature[i]; } catch(const CryptoPP::Exception& e) { cerr << e.what() << endl; return 1; } catch(std::length_error& le) { cerr << "Error: " << le.what() << endl; return 1; } return 0; }
size_t PEM_ReadLine(BufferedTransformation& source, SecByteBlock& line, SecByteBlock& ending) { if(!source.AnyRetrievable()) { line.New(0); ending.New(0); return 0; } ByteQueue temp; while(source.AnyRetrievable()) { byte b; if(!source.Get(b)) throw Exception(Exception::OTHER_ERROR, "PEM_ReadLine: failed to read byte"); // LF ? if(b == '\n') { ending = LF; break; } // CR ? if(b == '\r') { // CRLF ? if(source.AnyRetrievable() && source.Peek(b)) { if(b == '\n') { source.Skip(1); ending = CRLF; break; } } ending = CR; break; } // Not End-of-Line, accumulate it. temp.Put(b); } if(temp.AnyRetrievable()) { line.Grow(temp.MaxRetrievable()); temp.Get(line.data(), line.size()); } else { line.New(0); ending.New(0); } // We return a line stripped of CRs and LFs. However, we return the actual number of // of bytes processed, including the CR and LF. A return of 0 means nothing was read. // A return of 1 means an empty line was read (CR or LF). A return of 2 could // mean an empty line was read (CRLF), or could mean 1 character was read. In // any case, line will hold whatever was parsed. return line.size() + ending.size(); }