henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2012 The WebRTC Project Authors. All rights reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | #include "webrtc/p2p/base/transportdescriptionfactory.h" |
| 12 | |
kwiberg | 3ec4679 | 2016-04-27 07:22:53 -0700 | [diff] [blame] | 13 | #include <memory> |
| 14 | |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 15 | #include "webrtc/p2p/base/transportdescription.h" |
Edward Lemur | c20978e | 2017-07-06 19:44:34 +0200 | [diff] [blame] | 16 | #include "webrtc/rtc_base/helpers.h" |
| 17 | #include "webrtc/rtc_base/logging.h" |
| 18 | #include "webrtc/rtc_base/messagedigest.h" |
| 19 | #include "webrtc/rtc_base/sslfingerprint.h" |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 20 | |
| 21 | namespace cricket { |
| 22 | |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 23 | TransportDescriptionFactory::TransportDescriptionFactory() |
Peter Thatcher | 7cbd188 | 2015-09-17 18:54:52 -0700 | [diff] [blame] | 24 | : secure_(SEC_DISABLED) { |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | TransportDescription* TransportDescriptionFactory::CreateOffer( |
| 28 | const TransportOptions& options, |
| 29 | const TransportDescription* current_description) const { |
kwiberg | 3ec4679 | 2016-04-27 07:22:53 -0700 | [diff] [blame] | 30 | std::unique_ptr<TransportDescription> desc(new TransportDescription()); |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 31 | |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 32 | // Generate the ICE credentials if we don't already have them. |
| 33 | if (!current_description || options.ice_restart) { |
| 34 | desc->ice_ufrag = rtc::CreateRandomString(ICE_UFRAG_LENGTH); |
| 35 | desc->ice_pwd = rtc::CreateRandomString(ICE_PWD_LENGTH); |
| 36 | } else { |
| 37 | desc->ice_ufrag = current_description->ice_ufrag; |
| 38 | desc->ice_pwd = current_description->ice_pwd; |
| 39 | } |
deadbeef | 30952b4 | 2017-04-21 02:41:29 -0700 | [diff] [blame] | 40 | desc->AddOption(ICE_OPTION_TRICKLE); |
Honghai Zhang | 4cedf2b | 2016-08-31 08:18:11 -0700 | [diff] [blame] | 41 | if (options.enable_ice_renomination) { |
deadbeef | 30952b4 | 2017-04-21 02:41:29 -0700 | [diff] [blame] | 42 | desc->AddOption(ICE_OPTION_RENOMINATION); |
Honghai Zhang | 4cedf2b | 2016-08-31 08:18:11 -0700 | [diff] [blame] | 43 | } |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 44 | |
| 45 | // If we are trying to establish a secure transport, add a fingerprint. |
| 46 | if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) { |
| 47 | // Fail if we can't create the fingerprint. |
| 48 | // If we are the initiator set role to "actpass". |
| 49 | if (!SetSecurityInfo(desc.get(), CONNECTIONROLE_ACTPASS)) { |
| 50 | return NULL; |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | return desc.release(); |
| 55 | } |
| 56 | |
| 57 | TransportDescription* TransportDescriptionFactory::CreateAnswer( |
| 58 | const TransportDescription* offer, |
| 59 | const TransportOptions& options, |
deadbeef | b789253 | 2017-02-22 19:35:18 -0800 | [diff] [blame] | 60 | bool require_transport_attributes, |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 61 | const TransportDescription* current_description) const { |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 62 | // TODO(juberti): Figure out why we get NULL offers, and fix this upstream. |
Peter Thatcher | 7cbd188 | 2015-09-17 18:54:52 -0700 | [diff] [blame] | 63 | if (!offer) { |
| 64 | LOG(LS_WARNING) << "Failed to create TransportDescription answer " << |
| 65 | "because offer is NULL"; |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 66 | return NULL; |
| 67 | } |
| 68 | |
kwiberg | 3ec4679 | 2016-04-27 07:22:53 -0700 | [diff] [blame] | 69 | std::unique_ptr<TransportDescription> desc(new TransportDescription()); |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 70 | // Generate the ICE credentials if we don't already have them or ice is |
| 71 | // being restarted. |
| 72 | if (!current_description || options.ice_restart) { |
| 73 | desc->ice_ufrag = rtc::CreateRandomString(ICE_UFRAG_LENGTH); |
| 74 | desc->ice_pwd = rtc::CreateRandomString(ICE_PWD_LENGTH); |
| 75 | } else { |
| 76 | desc->ice_ufrag = current_description->ice_ufrag; |
| 77 | desc->ice_pwd = current_description->ice_pwd; |
| 78 | } |
deadbeef | 30952b4 | 2017-04-21 02:41:29 -0700 | [diff] [blame] | 79 | desc->AddOption(ICE_OPTION_TRICKLE); |
Honghai Zhang | 4cedf2b | 2016-08-31 08:18:11 -0700 | [diff] [blame] | 80 | if (options.enable_ice_renomination) { |
deadbeef | 30952b4 | 2017-04-21 02:41:29 -0700 | [diff] [blame] | 81 | desc->AddOption(ICE_OPTION_RENOMINATION); |
Honghai Zhang | 4cedf2b | 2016-08-31 08:18:11 -0700 | [diff] [blame] | 82 | } |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 83 | |
| 84 | // Negotiate security params. |
| 85 | if (offer && offer->identity_fingerprint.get()) { |
| 86 | // The offer supports DTLS, so answer with DTLS, as long as we support it. |
| 87 | if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) { |
| 88 | // Fail if we can't create the fingerprint. |
| 89 | // Setting DTLS role to active. |
| 90 | ConnectionRole role = (options.prefer_passive_role) ? |
| 91 | CONNECTIONROLE_PASSIVE : CONNECTIONROLE_ACTIVE; |
| 92 | |
| 93 | if (!SetSecurityInfo(desc.get(), role)) { |
| 94 | return NULL; |
| 95 | } |
| 96 | } |
deadbeef | b789253 | 2017-02-22 19:35:18 -0800 | [diff] [blame] | 97 | } else if (require_transport_attributes && secure_ == SEC_REQUIRED) { |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 98 | // We require DTLS, but the other side didn't offer it. Fail. |
| 99 | LOG(LS_WARNING) << "Failed to create TransportDescription answer " |
| 100 | "because of incompatible security settings"; |
| 101 | return NULL; |
| 102 | } |
| 103 | |
| 104 | return desc.release(); |
| 105 | } |
| 106 | |
| 107 | bool TransportDescriptionFactory::SetSecurityInfo( |
| 108 | TransportDescription* desc, ConnectionRole role) const { |
Henrik Boström | 3a14bf3 | 2015-08-31 09:27:58 +0200 | [diff] [blame] | 109 | if (!certificate_) { |
| 110 | LOG(LS_ERROR) << "Cannot create identity digest with no certificate"; |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 111 | return false; |
| 112 | } |
| 113 | |
| 114 | // This digest algorithm is used to produce the a=fingerprint lines in SDP. |
| 115 | // RFC 4572 Section 5 requires that those lines use the same hash function as |
deadbeef | 8662f94 | 2017-01-20 21:20:51 -0800 | [diff] [blame] | 116 | // the certificate's signature, which is what CreateFromCertificate does. |
| 117 | desc->identity_fingerprint.reset( |
| 118 | rtc::SSLFingerprint::CreateFromCertificate(certificate_)); |
| 119 | if (!desc->identity_fingerprint) { |
| 120 | return false; |
| 121 | } |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 122 | std::string digest_alg; |
Henrik Boström | 3a14bf3 | 2015-08-31 09:27:58 +0200 | [diff] [blame] | 123 | if (!certificate_->ssl_certificate().GetSignatureDigestAlgorithm( |
| 124 | &digest_alg)) { |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 125 | LOG(LS_ERROR) << "Failed to retrieve the certificate's digest algorithm"; |
| 126 | return false; |
| 127 | } |
| 128 | |
| 129 | desc->identity_fingerprint.reset( |
Henrik Boström | 3a14bf3 | 2015-08-31 09:27:58 +0200 | [diff] [blame] | 130 | rtc::SSLFingerprint::Create(digest_alg, certificate_->identity())); |
henrike@webrtc.org | 269fb4b | 2014-10-28 22:20:11 +0000 | [diff] [blame] | 131 | if (!desc->identity_fingerprint.get()) { |
| 132 | LOG(LS_ERROR) << "Failed to create identity fingerprint, alg=" |
| 133 | << digest_alg; |
| 134 | return false; |
| 135 | } |
| 136 | |
| 137 | // Assign security role. |
| 138 | desc->connection_role = role; |
| 139 | return true; |
| 140 | } |
| 141 | |
| 142 | } // namespace cricket |