blob: b9b7cf34d1b9516a75dc6b7cded499e605588f61 [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
11#include "public-key.hpp"
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080012
Junxiao Shi482ccc52014-03-31 13:05:24 -070013#include "cryptopp.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070014
15using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080016using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070017
18namespace ndn {
19
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080020static OID RSA_OID("1.2.840.113549.1.1.1");
Jeff Thompsonc0573432013-09-19 17:41:36 -070021
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080022PublicKey::PublicKey()
23{
Jeff Thompsonc0573432013-09-19 17:41:36 -070024}
Jeff Thompsonc0573432013-09-19 17:41:36 -070025
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080026/**
27 * Create a new PublicKey with the given values.
28 * @param algorithm The algorithm of the public key.
29 * @param keyDer The blob of the PublicKeyInfo in terms of DER.
30 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070031PublicKey::PublicKey(const uint8_t* keyDerBuf, size_t keyDerSize)
Jeff Thompsonc0573432013-09-19 17:41:36 -070032{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080033 StringSource src(keyDerBuf, keyDerSize, true);
34 decode(src);
Jeff Thompsonc0573432013-09-19 17:41:36 -070035}
36
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080037void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038PublicKey::encode(CryptoPP::BufferedTransformation& out) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070039{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080040 // SubjectPublicKeyInfo ::= SEQUENCE {
41 // algorithm AlgorithmIdentifier
42 // keybits BIT STRING }
43
44 out.Put(key_.buf(), key_.size());
45}
46
47void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070048PublicKey::decode(CryptoPP::BufferedTransformation& in)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080049{
50 // SubjectPublicKeyInfo ::= SEQUENCE {
51 // algorithm AlgorithmIdentifier
52 // keybits BIT STRING }
53
54 try {
55 std::string out;
56 StringSink sink(out);
57
58 ////////////////////////
59 // part 1: copy as is //
60 ////////////////////////
61 BERSequenceDecoder decoder(in);
62 {
63 assert (decoder.IsDefiniteLength());
64
65 DERSequenceEncoder encoder(sink);
66 decoder.TransferTo(encoder, decoder.RemainingLength());
67 encoder.MessageEnd();
68 }
69 decoder.MessageEnd();
70
71 ////////////////////////
72 // part 2: check if the key is RSA (since it is the only supported for now)
73 ////////////////////////
74 StringSource checkedSource(out, true);
75 BERSequenceDecoder subjectPublicKeyInfo(checkedSource);
76 {
77 BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
78 {
79 OID algorithm;
80 algorithm.decode(algorithmInfo);
81
82 if (algorithm != RSA_OID)
83 throw Error("Only RSA public keys are supported for now (" + algorithm.toString() + " requested");
84 }
85 }
86
87 key_.assign(out.begin(), out.end());
Jeff Thompsonc0573432013-09-19 17:41:36 -070088 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070089 catch (CryptoPP::BERDecodeErr& err) {
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080090 throw Error("PublicKey decoding error");
91 }
92}
93
94// Blob
95// PublicKey::getDigest(DigestAlgorithm digestAlgorithm) const
96// {
97// if (digestAlgorithm == DIGEST_ALGORITHM_SHA256) {
98// uint8_t digest[SHA256_DIGEST_LENGTH];
99// ndn_digestSha256(keyDer_.buf(), keyDer_.size(), digest);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700100
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800101// return Blob(digest, sizeof(digest));
102// }
103// else
104// throw UnrecognizedDigestAlgorithmException("Wrong format!");
105// }
106
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700107std::ostream&
108operator <<(std::ostream& os, const PublicKey& key)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800109{
110 CryptoPP::StringSource(key.get().buf(), key.get().size(), true,
111 new CryptoPP::Base64Encoder(new CryptoPP::FileSink(os), true, 64));
112
113 return os;
Jeff Thompsonc0573432013-09-19 17:41:36 -0700114}
115
Yingdi Yufc40d872014-02-18 12:56:04 -0800116} // namespace ndn