| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "remoting/protocol/v1_authenticator.h" | |
| 6 | |
| 7 #include "base/base64.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "crypto/rsa_private_key.h" | |
| 10 #include "remoting/base/constants.h" | |
| 11 #include "remoting/protocol/auth_util.h" | |
| 12 #include "remoting/protocol/ssl_hmac_channel_authenticator.h" | |
| 13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | |
| 14 | |
| 15 using buzz::QName; | |
| 16 using buzz::XmlElement; | |
| 17 | |
| 18 namespace remoting { | |
| 19 namespace protocol { | |
| 20 | |
| 21 namespace { | |
| 22 const char kAuthTokenTag[] = "auth-token"; | |
| 23 const char kCertificateTag[] = "certificate"; | |
| 24 } // namespace | |
| 25 | |
| 26 V1ClientAuthenticator::V1ClientAuthenticator( | |
| 27 const std::string& local_jid, | |
| 28 const std::string& shared_secret) | |
| 29 : local_jid_(local_jid), | |
| 30 shared_secret_(shared_secret), | |
| 31 state_(MESSAGE_READY), | |
| 32 rejection_reason_(INVALID_CREDENTIALS) { | |
| 33 } | |
| 34 | |
| 35 V1ClientAuthenticator::~V1ClientAuthenticator() { | |
| 36 } | |
| 37 | |
| 38 Authenticator::State V1ClientAuthenticator::state() const { | |
| 39 return state_; | |
| 40 } | |
| 41 | |
| 42 Authenticator::RejectionReason V1ClientAuthenticator::rejection_reason() const { | |
| 43 DCHECK_EQ(state_, REJECTED); | |
| 44 return rejection_reason_; | |
| 45 } | |
| 46 | |
| 47 void V1ClientAuthenticator::ProcessMessage(const XmlElement* message) { | |
| 48 DCHECK_EQ(state_, WAITING_MESSAGE); | |
| 49 | |
| 50 // Parse the certificate. | |
| 51 const XmlElement* cert_tag = | |
| 52 message->FirstNamed(QName(kChromotingXmlNamespace, kCertificateTag)); | |
| 53 if (cert_tag) { | |
| 54 std::string base64_cert = cert_tag->BodyText(); | |
| 55 if (!base::Base64Decode(base64_cert, &remote_cert_)) { | |
| 56 LOG(ERROR) << "Failed to decode certificate received from the peer."; | |
| 57 remote_cert_.clear(); | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 if (remote_cert_.empty()) { | |
| 62 state_ = REJECTED; | |
| 63 rejection_reason_ = PROTOCOL_ERROR; | |
| 64 } else { | |
| 65 state_ = ACCEPTED; | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 scoped_ptr<XmlElement> V1ClientAuthenticator::GetNextMessage() { | |
| 70 DCHECK_EQ(state_, MESSAGE_READY); | |
| 71 | |
| 72 scoped_ptr<XmlElement> message = CreateEmptyAuthenticatorMessage(); | |
| 73 std::string token = | |
| 74 protocol::GenerateSupportAuthToken(local_jid_, shared_secret_); | |
| 75 XmlElement* auth_token_tag = new XmlElement( | |
| 76 QName(kChromotingXmlNamespace, kAuthTokenTag)); | |
| 77 auth_token_tag->SetBodyText(token); | |
| 78 message->AddElement(auth_token_tag); | |
| 79 | |
| 80 state_ = WAITING_MESSAGE; | |
| 81 return message.Pass(); | |
| 82 } | |
| 83 | |
| 84 scoped_ptr<ChannelAuthenticator> | |
| 85 V1ClientAuthenticator::CreateChannelAuthenticator() const { | |
| 86 DCHECK_EQ(state_, ACCEPTED); | |
| 87 scoped_ptr<SslHmacChannelAuthenticator> result = | |
| 88 SslHmacChannelAuthenticator::CreateForClient( | |
| 89 remote_cert_, shared_secret_); | |
| 90 result->SetLegacyOneWayMode(SslHmacChannelAuthenticator::SEND_ONLY); | |
| 91 return result.PassAs<ChannelAuthenticator>(); | |
| 92 }; | |
| 93 | |
| 94 V1HostAuthenticator::V1HostAuthenticator( | |
| 95 const std::string& local_cert, | |
| 96 const crypto::RSAPrivateKey& local_private_key, | |
| 97 const std::string& shared_secret, | |
| 98 const std::string& remote_jid) | |
| 99 : local_cert_(local_cert), | |
| 100 local_private_key_(local_private_key.Copy()), | |
| 101 shared_secret_(shared_secret), | |
| 102 remote_jid_(remote_jid), | |
| 103 state_(WAITING_MESSAGE), | |
| 104 rejection_reason_(INVALID_CREDENTIALS) { | |
| 105 } | |
| 106 | |
| 107 V1HostAuthenticator::~V1HostAuthenticator() { | |
| 108 } | |
| 109 | |
| 110 Authenticator::State V1HostAuthenticator::state() const { | |
| 111 return state_; | |
| 112 } | |
| 113 | |
| 114 Authenticator::RejectionReason V1HostAuthenticator::rejection_reason() const { | |
| 115 DCHECK_EQ(state_, REJECTED); | |
| 116 return rejection_reason_; | |
| 117 } | |
| 118 | |
| 119 void V1HostAuthenticator::ProcessMessage(const XmlElement* message) { | |
| 120 DCHECK_EQ(state_, WAITING_MESSAGE); | |
| 121 | |
| 122 std::string auth_token = | |
| 123 message->TextNamed(buzz::QName(kChromotingXmlNamespace, kAuthTokenTag)); | |
| 124 | |
| 125 if (auth_token.empty()) { | |
| 126 state_ = REJECTED; | |
| 127 rejection_reason_ = PROTOCOL_ERROR; | |
| 128 return; | |
| 129 } | |
| 130 | |
| 131 if (!protocol::VerifySupportAuthToken( | |
| 132 remote_jid_, shared_secret_, auth_token)) { | |
| 133 state_ = REJECTED; | |
| 134 rejection_reason_ = INVALID_CREDENTIALS; | |
| 135 } else { | |
| 136 state_ = MESSAGE_READY; | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 scoped_ptr<XmlElement> V1HostAuthenticator::GetNextMessage() { | |
| 141 DCHECK_EQ(state_, MESSAGE_READY); | |
| 142 | |
| 143 scoped_ptr<XmlElement> message = CreateEmptyAuthenticatorMessage(); | |
| 144 buzz::XmlElement* certificate_tag = new XmlElement( | |
| 145 buzz::QName(kChromotingXmlNamespace, kCertificateTag)); | |
| 146 std::string base64_cert; | |
| 147 if (!base::Base64Encode(local_cert_, &base64_cert)) { | |
| 148 LOG(DFATAL) << "Cannot perform base64 encode on certificate"; | |
| 149 } | |
| 150 certificate_tag->SetBodyText(base64_cert); | |
| 151 message->AddElement(certificate_tag); | |
| 152 | |
| 153 state_ = ACCEPTED; | |
| 154 return message.Pass(); | |
| 155 } | |
| 156 | |
| 157 scoped_ptr<ChannelAuthenticator> | |
| 158 V1HostAuthenticator::CreateChannelAuthenticator() const { | |
| 159 DCHECK_EQ(state_, ACCEPTED); | |
| 160 scoped_ptr<SslHmacChannelAuthenticator> result = | |
| 161 SslHmacChannelAuthenticator::CreateForHost( | |
| 162 local_cert_, local_private_key_.get(), shared_secret_); | |
| 163 result->SetLegacyOneWayMode(SslHmacChannelAuthenticator::RECEIVE_ONLY); | |
| 164 return result.PassAs<ChannelAuthenticator>(); | |
| 165 }; | |
| 166 | |
| 167 } // namespace remoting | |
| 168 } // namespace protocol | |
| OLD | NEW |