blob: 67b57bb66c52e46885531e23446336756d24bb44 [file] [log] [blame]
Jeff Thompsonc0573432013-09-19 17:41:36 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
6 * See COPYING for copyright and distribution information.
7 */
8
Alexander Afanasyev09c613f2014-01-29 00:23:58 -08009#include "common.hpp"
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080010#include "public-key.hpp"
Junxiao Shi482ccc52014-03-31 13:05:24 -070011#include "cryptopp.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070012
13using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080014using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070015
16namespace ndn {
17
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080018static OID RSA_OID("1.2.840.113549.1.1.1");
Jeff Thompsonc0573432013-09-19 17:41:36 -070019
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080020PublicKey::PublicKey()
21{
Jeff Thompsonc0573432013-09-19 17:41:36 -070022}
Jeff Thompsonc0573432013-09-19 17:41:36 -070023
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080024/**
25 * Create a new PublicKey with the given values.
26 * @param algorithm The algorithm of the public key.
27 * @param keyDer The blob of the PublicKeyInfo in terms of DER.
28 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070029PublicKey::PublicKey(const uint8_t* keyDerBuf, size_t keyDerSize)
Jeff Thompsonc0573432013-09-19 17:41:36 -070030{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080031 StringSource src(keyDerBuf, keyDerSize, true);
32 decode(src);
Jeff Thompsonc0573432013-09-19 17:41:36 -070033}
34
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080035void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070036PublicKey::encode(CryptoPP::BufferedTransformation& out) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070037{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080038 // SubjectPublicKeyInfo ::= SEQUENCE {
39 // algorithm AlgorithmIdentifier
40 // keybits BIT STRING }
41
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070042 out.Put(m_key.buf(), m_key.size());
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080043}
44
45void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070046PublicKey::decode(CryptoPP::BufferedTransformation& in)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080047{
48 // SubjectPublicKeyInfo ::= SEQUENCE {
49 // algorithm AlgorithmIdentifier
50 // keybits BIT STRING }
51
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070052 try
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080053 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070054 std::string out;
55 StringSink sink(out);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080056
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070057 ////////////////////////
58 // part 1: copy as is //
59 ////////////////////////
60 BERSequenceDecoder decoder(in);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080061 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070062 assert(decoder.IsDefiniteLength());
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080063
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070064 DERSequenceEncoder encoder(sink);
65 decoder.TransferTo(encoder, decoder.RemainingLength());
66 encoder.MessageEnd();
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080067 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070068 decoder.MessageEnd();
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080069
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070070 ////////////////////////
71 // part 2: check if the key is RSA (since it is the only supported for now)
72 ////////////////////////
73 StringSource checkedSource(out, true);
74 BERSequenceDecoder subjectPublicKeyInfo(checkedSource);
75 {
76 BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
77 {
78 OID algorithm;
79 algorithm.decode(algorithmInfo);
80
81 if (algorithm != RSA_OID)
82 throw Error("Only RSA public keys are supported for now (" +
83 algorithm.toString() + " requested)");
84 }
85 }
86
87 m_key.assign(out.begin(), out.end());
88 }
89 catch (CryptoPP::BERDecodeErr& err)
90 {
91 throw Error("PublicKey decoding error");
92 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080093}
94
95// Blob
96// PublicKey::getDigest(DigestAlgorithm digestAlgorithm) const
97// {
98// if (digestAlgorithm == DIGEST_ALGORITHM_SHA256) {
99// uint8_t digest[SHA256_DIGEST_LENGTH];
100// ndn_digestSha256(keyDer_.buf(), keyDer_.size(), digest);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800102// return Blob(digest, sizeof(digest));
103// }
104// else
105// throw UnrecognizedDigestAlgorithmException("Wrong format!");
106// }
107
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700108std::ostream&
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700109operator<<(std::ostream& os, const PublicKey& key)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800110{
111 CryptoPP::StringSource(key.get().buf(), key.get().size(), true,
112 new CryptoPP::Base64Encoder(new CryptoPP::FileSink(os), true, 64));
113
114 return os;
Jeff Thompsonc0573432013-09-19 17:41:36 -0700115}
116
Yingdi Yufc40d872014-02-18 12:56:04 -0800117} // namespace ndn