blob: 9449cc938678af2a7d42efe8a77494cd52ffe5c8 [file] [log] [blame]
Jeff Thompsonc0573432013-09-19 17:41:36 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
13 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Jeff Thompsonc0573432013-09-19 17:41:36 -070014 */
15
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080016#include "common.hpp"
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080017#include "public-key.hpp"
Junxiao Shi482ccc52014-03-31 13:05:24 -070018#include "cryptopp.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070019
20using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080021using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070022
23namespace ndn {
24
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080025static OID RSA_OID("1.2.840.113549.1.1.1");
Jeff Thompsonc0573432013-09-19 17:41:36 -070026
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080027PublicKey::PublicKey()
28{
Jeff Thompsonc0573432013-09-19 17:41:36 -070029}
Jeff Thompsonc0573432013-09-19 17:41:36 -070030
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080031/**
32 * Create a new PublicKey with the given values.
33 * @param algorithm The algorithm of the public key.
34 * @param keyDer The blob of the PublicKeyInfo in terms of DER.
35 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070036PublicKey::PublicKey(const uint8_t* keyDerBuf, size_t keyDerSize)
Jeff Thompsonc0573432013-09-19 17:41:36 -070037{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080038 StringSource src(keyDerBuf, keyDerSize, true);
39 decode(src);
Jeff Thompsonc0573432013-09-19 17:41:36 -070040}
41
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080042void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070043PublicKey::encode(CryptoPP::BufferedTransformation& out) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070044{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080045 // SubjectPublicKeyInfo ::= SEQUENCE {
46 // algorithm AlgorithmIdentifier
47 // keybits BIT STRING }
48
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070049 out.Put(m_key.buf(), m_key.size());
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080050}
51
52void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053PublicKey::decode(CryptoPP::BufferedTransformation& in)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080054{
55 // SubjectPublicKeyInfo ::= SEQUENCE {
56 // algorithm AlgorithmIdentifier
57 // keybits BIT STRING }
58
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070059 try
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080060 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070061 std::string out;
62 StringSink sink(out);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080063
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070064 ////////////////////////
65 // part 1: copy as is //
66 ////////////////////////
67 BERSequenceDecoder decoder(in);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080068 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070069 assert(decoder.IsDefiniteLength());
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080070
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070071 DERSequenceEncoder encoder(sink);
72 decoder.TransferTo(encoder, decoder.RemainingLength());
73 encoder.MessageEnd();
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080074 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070075 decoder.MessageEnd();
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080076
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070077 ////////////////////////
78 // part 2: check if the key is RSA (since it is the only supported for now)
79 ////////////////////////
80 StringSource checkedSource(out, true);
81 BERSequenceDecoder subjectPublicKeyInfo(checkedSource);
82 {
83 BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
84 {
85 OID algorithm;
86 algorithm.decode(algorithmInfo);
87
88 if (algorithm != RSA_OID)
89 throw Error("Only RSA public keys are supported for now (" +
90 algorithm.toString() + " requested)");
91 }
92 }
93
94 m_key.assign(out.begin(), out.end());
95 }
96 catch (CryptoPP::BERDecodeErr& err)
97 {
98 throw Error("PublicKey decoding error");
99 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800100}
101
102// Blob
103// PublicKey::getDigest(DigestAlgorithm digestAlgorithm) const
104// {
105// if (digestAlgorithm == DIGEST_ALGORITHM_SHA256) {
106// uint8_t digest[SHA256_DIGEST_LENGTH];
107// ndn_digestSha256(keyDer_.buf(), keyDer_.size(), digest);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700108
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800109// return Blob(digest, sizeof(digest));
110// }
111// else
112// throw UnrecognizedDigestAlgorithmException("Wrong format!");
113// }
114
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700115std::ostream&
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700116operator<<(std::ostream& os, const PublicKey& key)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800117{
118 CryptoPP::StringSource(key.get().buf(), key.get().size(), true,
119 new CryptoPP::Base64Encoder(new CryptoPP::FileSink(os), true, 64));
120
121 return os;
Jeff Thompsonc0573432013-09-19 17:41:36 -0700122}
123
Yingdi Yufc40d872014-02-18 12:56:04 -0800124} // namespace ndn