blob: 6666783f2039719aa07a7e1592935bc2be3264b9 [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 Afanasyev736708b2014-01-06 14:45:34 -08009#if __clang__
10#pragma clang diagnostic push
11#pragma clang diagnostic ignored "-Wreorder"
12#pragma clang diagnostic ignored "-Wtautological-compare"
13#pragma clang diagnostic ignored "-Wunused-variable"
14#pragma clang diagnostic ignored "-Wunused-function"
15#elif __GNUC__
16#pragma GCC diagnostic ignored "-Wreorder"
17#pragma GCC diagnostic ignored "-Wtautological-compare"
18#pragma GCC diagnostic ignored "-Wunused-variable"
19#pragma GCC diagnostic ignored "-Wunused-function"
20#endif
21
Alexander Afanasyev8e96e582013-11-19 12:07:04 -080022#include <ndn-cpp/common.hpp>
Alexander Afanasyev6be1a6a2014-01-06 00:08:14 -080023#include <ndn-cpp/security/certificate/public-key.hpp>
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080024
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080025#include <cryptopp/rsa.h>
26#include <cryptopp/base64.h>
27#include <cryptopp/files.h>
Jeff Thompsonc0573432013-09-19 17:41:36 -070028
29using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080030using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070031
32namespace ndn {
33
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080034static OID RSA_OID("1.2.840.113549.1.1.1");
Jeff Thompsonc0573432013-09-19 17:41:36 -070035
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080036PublicKey::PublicKey()
37{
Jeff Thompsonc0573432013-09-19 17:41:36 -070038}
Jeff Thompsonc0573432013-09-19 17:41:36 -070039
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080040/**
41 * Create a new PublicKey with the given values.
42 * @param algorithm The algorithm of the public key.
43 * @param keyDer The blob of the PublicKeyInfo in terms of DER.
44 */
45PublicKey::PublicKey(const uint8_t *keyDerBuf, size_t keyDerSize)
Jeff Thompsonc0573432013-09-19 17:41:36 -070046{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080047 StringSource src(keyDerBuf, keyDerSize, true);
48 decode(src);
Jeff Thompsonc0573432013-09-19 17:41:36 -070049}
50
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080051void
52PublicKey::encode(CryptoPP::BufferedTransformation &out) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070053{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080054 // SubjectPublicKeyInfo ::= SEQUENCE {
55 // algorithm AlgorithmIdentifier
56 // keybits BIT STRING }
57
58 out.Put(key_.buf(), key_.size());
59}
60
61void
62PublicKey::decode(CryptoPP::BufferedTransformation &in)
63{
64 // SubjectPublicKeyInfo ::= SEQUENCE {
65 // algorithm AlgorithmIdentifier
66 // keybits BIT STRING }
67
68 try {
69 std::string out;
70 StringSink sink(out);
71
72 ////////////////////////
73 // part 1: copy as is //
74 ////////////////////////
75 BERSequenceDecoder decoder(in);
76 {
77 assert (decoder.IsDefiniteLength());
78
79 DERSequenceEncoder encoder(sink);
80 decoder.TransferTo(encoder, decoder.RemainingLength());
81 encoder.MessageEnd();
82 }
83 decoder.MessageEnd();
84
85 ////////////////////////
86 // part 2: check if the key is RSA (since it is the only supported for now)
87 ////////////////////////
88 StringSource checkedSource(out, true);
89 BERSequenceDecoder subjectPublicKeyInfo(checkedSource);
90 {
91 BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
92 {
93 OID algorithm;
94 algorithm.decode(algorithmInfo);
95
96 if (algorithm != RSA_OID)
97 throw Error("Only RSA public keys are supported for now (" + algorithm.toString() + " requested");
98 }
99 }
100
101 key_.assign(out.begin(), out.end());
Jeff Thompsonc0573432013-09-19 17:41:36 -0700102 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800103 catch (CryptoPP::BERDecodeErr &err) {
104 throw Error("PublicKey decoding error");
105 }
106}
107
108// Blob
109// PublicKey::getDigest(DigestAlgorithm digestAlgorithm) const
110// {
111// if (digestAlgorithm == DIGEST_ALGORITHM_SHA256) {
112// uint8_t digest[SHA256_DIGEST_LENGTH];
113// ndn_digestSha256(keyDer_.buf(), keyDer_.size(), digest);
114
115// return Blob(digest, sizeof(digest));
116// }
117// else
118// throw UnrecognizedDigestAlgorithmException("Wrong format!");
119// }
120
121std::ostream &
122operator <<(std::ostream &os, const PublicKey &key)
123{
124 CryptoPP::StringSource(key.get().buf(), key.get().size(), true,
125 new CryptoPP::Base64Encoder(new CryptoPP::FileSink(os), true, 64));
126
127 return os;
Jeff Thompsonc0573432013-09-19 17:41:36 -0700128}
129
130}