1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/socket/ssl_client_socket.h"
- #include <errno.h>
- #include <string.h>
- #include <algorithm>
- #include <memory>
- #include <tuple>
- #include <utility>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/files/file_util.h"
- #include "base/location.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/ref_counted.h"
- #include "base/run_loop.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/strings/string_piece.h"
- #include "base/strings/stringprintf.h"
- #include "base/synchronization/lock.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/test/bind.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/time/time.h"
- #include "base/values.h"
- #include "build/build_config.h"
- #include "crypto/rsa_private_key.h"
- #include "net/base/address_list.h"
- #include "net/base/completion_once_callback.h"
- #include "net/base/features.h"
- #include "net/base/io_buffer.h"
- #include "net/base/ip_address.h"
- #include "net/base/ip_endpoint.h"
- #include "net/base/net_errors.h"
- #include "net/base/network_isolation_key.h"
- #include "net/base/schemeful_site.h"
- #include "net/base/test_completion_callback.h"
- #include "net/cert/asn1_util.h"
- #include "net/cert/cert_and_ct_verifier.h"
- #include "net/cert/ct_policy_enforcer.h"
- #include "net/cert/ct_policy_status.h"
- #include "net/cert/ct_verifier.h"
- #include "net/cert/do_nothing_ct_verifier.h"
- #include "net/cert/mock_cert_verifier.h"
- #include "net/cert/mock_client_cert_verifier.h"
- #include "net/cert/sct_auditing_delegate.h"
- #include "net/cert/signed_certificate_timestamp_and_status.h"
- #include "net/cert/test_root_certs.h"
- #include "net/cert/x509_util.h"
- #include "net/der/input.h"
- #include "net/der/parser.h"
- #include "net/der/tag.h"
- #include "net/dns/host_resolver.h"
- #include "net/http/transport_security_state.h"
- #include "net/http/transport_security_state_test_util.h"
- #include "net/log/net_log_event_type.h"
- #include "net/log/net_log_source.h"
- #include "net/log/test_net_log.h"
- #include "net/log/test_net_log_util.h"
- #include "net/socket/client_socket_factory.h"
- #include "net/socket/client_socket_handle.h"
- #include "net/socket/read_buffering_stream_socket.h"
- #include "net/socket/socket_test_util.h"
- #include "net/socket/ssl_server_socket.h"
- #include "net/socket/stream_socket.h"
- #include "net/socket/tcp_client_socket.h"
- #include "net/socket/tcp_server_socket.h"
- #include "net/ssl/ssl_cert_request_info.h"
- #include "net/ssl/ssl_client_session_cache.h"
- #include "net/ssl/ssl_config.h"
- #include "net/ssl/ssl_config_service.h"
- #include "net/ssl/ssl_connection_status_flags.h"
- #include "net/ssl/ssl_handshake_details.h"
- #include "net/ssl/ssl_info.h"
- #include "net/ssl/ssl_server_config.h"
- #include "net/ssl/test_ssl_config_service.h"
- #include "net/ssl/test_ssl_private_key.h"
- #include "net/test/cert_test_util.h"
- #include "net/test/embedded_test_server/embedded_test_server.h"
- #include "net/test/embedded_test_server/http_request.h"
- #include "net/test/embedded_test_server/http_response.h"
- #include "net/test/gtest_util.h"
- #include "net/test/key_util.h"
- #include "net/test/ssl_test_util.h"
- #include "net/test/test_data_directory.h"
- #include "net/test/test_with_task_environment.h"
- #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "testing/platform_test.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "third_party/boringssl/src/include/openssl/bio.h"
- #include "third_party/boringssl/src/include/openssl/evp.h"
- #include "third_party/boringssl/src/include/openssl/hpke.h"
- #include "third_party/boringssl/src/include/openssl/pem.h"
- #include "third_party/boringssl/src/include/openssl/ssl.h"
- #include "url/gurl.h"
- using net::test::IsError;
- using net::test::IsOk;
- using testing::_;
- using testing::Bool;
- using testing::Combine;
- using testing::Return;
- using testing::Values;
- using testing::ValuesIn;
- namespace net {
- class NetLogWithSource;
- namespace {
- // When passed to |MakeHashValueVector|, this will generate a key pin that is
- // sha256/AA...=, and hence will cause pin validation success with the TestSPKI
- // pin from transport_security_state_static.pins. ("A" is the 0th element of the
- // base-64 alphabet.)
- const uint8_t kGoodHashValueVectorInput = 0;
- // When passed to |MakeHashValueVector|, this will generate a key pin that is
- // not sha256/AA...=, and hence will cause pin validation failure with the
- // TestSPKI pin.
- const uint8_t kBadHashValueVectorInput = 3;
- // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- constexpr uint16_t kModernTLS12Cipher = 0xc02f;
- // TLS_RSA_WITH_AES_128_GCM_SHA256
- constexpr uint16_t kRSACipher = 0x009c;
- // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- constexpr uint16_t kCBCCipher = 0xc013;
- // TLS_RSA_WITH_3DES_EDE_CBC_SHA
- constexpr uint16_t k3DESCipher = 0x000a;
- // Simulates synchronously receiving an error during Read() or Write()
- class SynchronousErrorStreamSocket : public WrappedStreamSocket {
- public:
- explicit SynchronousErrorStreamSocket(std::unique_ptr<StreamSocket> transport)
- : WrappedStreamSocket(std::move(transport)) {}
- SynchronousErrorStreamSocket(const SynchronousErrorStreamSocket&) = delete;
- SynchronousErrorStreamSocket& operator=(const SynchronousErrorStreamSocket&) =
- delete;
- ~SynchronousErrorStreamSocket() override = default;
- // Socket implementation:
- int Read(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override;
- int ReadIfReady(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override;
- int Write(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback,
- const NetworkTrafficAnnotationTag& traffic_annotation) override;
- // Sets the next Read() call and all future calls to return |error|.
- // If there is already a pending asynchronous read, the configured error
- // will not be returned until that asynchronous read has completed and Read()
- // is called again.
- void SetNextReadError(int error) {
- DCHECK_GE(0, error);
- have_read_error_ = true;
- pending_read_error_ = error;
- }
- // Sets the next Write() call and all future calls to return |error|.
- // If there is already a pending asynchronous write, the configured error
- // will not be returned until that asynchronous write has completed and
- // Write() is called again.
- void SetNextWriteError(int error) {
- DCHECK_GE(0, error);
- have_write_error_ = true;
- pending_write_error_ = error;
- }
- private:
- bool have_read_error_ = false;
- int pending_read_error_ = OK;
- bool have_write_error_ = false;
- int pending_write_error_ = OK;
- };
- int SynchronousErrorStreamSocket::Read(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) {
- if (have_read_error_)
- return pending_read_error_;
- return transport_->Read(buf, buf_len, std::move(callback));
- }
- int SynchronousErrorStreamSocket::ReadIfReady(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) {
- if (have_read_error_)
- return pending_read_error_;
- return transport_->ReadIfReady(buf, buf_len, std::move(callback));
- }
- int SynchronousErrorStreamSocket::Write(
- IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback,
- const NetworkTrafficAnnotationTag& traffic_annotation) {
- if (have_write_error_)
- return pending_write_error_;
- return transport_->Write(buf, buf_len, std::move(callback),
- traffic_annotation);
- }
- // FakeBlockingStreamSocket wraps an existing StreamSocket and simulates the
- // underlying transport needing to complete things asynchronously in a
- // deterministic manner (e.g.: independent of the TestServer and the OS's
- // semantics).
- class FakeBlockingStreamSocket : public WrappedStreamSocket {
- public:
- explicit FakeBlockingStreamSocket(std::unique_ptr<StreamSocket> transport)
- : WrappedStreamSocket(std::move(transport)) {}
- ~FakeBlockingStreamSocket() override = default;
- // Socket implementation:
- int Read(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override;
- int ReadIfReady(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override;
- int CancelReadIfReady() override;
- int Write(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback,
- const NetworkTrafficAnnotationTag& traffic_annotation) override;
- int pending_read_result() const { return pending_read_result_; }
- IOBuffer* pending_read_buf() const { return pending_read_buf_.get(); }
- // Blocks read results on the socket. Reads will not complete until
- // UnblockReadResult() has been called and a result is ready from the
- // underlying transport. Note: if BlockReadResult() is called while there is a
- // hanging asynchronous Read(), that Read is blocked.
- void BlockReadResult();
- void UnblockReadResult();
- // Replaces the pending read with |data|. Returns true on success or false if
- // the caller's reads were too small.
- bool ReplaceReadResult(const std::string& data);
- // Waits for the blocked Read() call to be complete at the underlying
- // transport.
- void WaitForReadResult();
- // Causes the next call to Write() to return ERR_IO_PENDING, not beginning the
- // underlying transport until UnblockWrite() has been called. Note: if there
- // is a pending asynchronous write, it is NOT blocked. For purposes of
- // blocking writes, data is considered to have reached the underlying
- // transport as soon as Write() is called.
- void BlockWrite();
- void UnblockWrite();
- // Waits for the blocked Write() call to be scheduled.
- void WaitForWrite();
- private:
- // Handles completion from the underlying transport read.
- void OnReadCompleted(int result);
- // Handles async completion of ReadIfReady().
- void CompleteReadIfReady(scoped_refptr<IOBuffer> buffer, int rv);
- // Finishes the current read.
- void ReturnReadResult();
- // Callback for writes.
- void CallPendingWriteCallback(int result);
- // True if read callbacks are blocked.
- bool should_block_read_ = false;
- // Used to buffer result returned by a completed ReadIfReady().
- std::string read_if_ready_buf_;
- // Non-null if there is a pending ReadIfReady().
- CompletionOnceCallback read_if_ready_callback_;
- // The buffer for the pending read, or NULL if not consumed.
- scoped_refptr<IOBuffer> pending_read_buf_;
- // The size of the pending read buffer, or -1 if not set.
- int pending_read_buf_len_ = -1;
- // The user callback for the pending read call.
- CompletionOnceCallback pending_read_callback_;
- // The result for the blocked read callback, or ERR_IO_PENDING if not
- // completed.
- int pending_read_result_ = ERR_IO_PENDING;
- // WaitForReadResult() wait loop.
- std::unique_ptr<base::RunLoop> read_loop_;
- // True if write calls are blocked.
- bool should_block_write_ = false;
- // The buffer for the pending write, or NULL if not scheduled.
- scoped_refptr<IOBuffer> pending_write_buf_;
- // The callback for the pending write call.
- CompletionOnceCallback pending_write_callback_;
- // The length for the pending write, or -1 if not scheduled.
- int pending_write_len_ = -1;
- // WaitForWrite() wait loop.
- std::unique_ptr<base::RunLoop> write_loop_;
- };
- int FakeBlockingStreamSocket::Read(IOBuffer* buf,
- int len,
- CompletionOnceCallback callback) {
- DCHECK(!pending_read_buf_);
- DCHECK(pending_read_callback_.is_null());
- DCHECK_EQ(ERR_IO_PENDING, pending_read_result_);
- DCHECK(!callback.is_null());
- int rv = transport_->Read(
- buf, len,
- base::BindOnce(&FakeBlockingStreamSocket::OnReadCompleted,
- base::Unretained(this)));
- if (rv == ERR_IO_PENDING || should_block_read_) {
- // Save the callback to be called later.
- pending_read_buf_ = buf;
- pending_read_buf_len_ = len;
- pending_read_callback_ = std::move(callback);
- // Save the read result.
- if (rv != ERR_IO_PENDING) {
- OnReadCompleted(rv);
- rv = ERR_IO_PENDING;
- }
- }
- return rv;
- }
- int FakeBlockingStreamSocket::ReadIfReady(IOBuffer* buf,
- int len,
- CompletionOnceCallback callback) {
- if (!read_if_ready_buf_.empty()) {
- // If ReadIfReady() is used, asynchronous reads with a large enough buffer
- // and no BlockReadResult() are supported by this class. Explicitly check
- // that |should_block_read_| doesn't apply and |len| is greater than the
- // size of the buffered data.
- CHECK(!should_block_read_);
- CHECK_GE(len, static_cast<int>(read_if_ready_buf_.size()));
- int rv = read_if_ready_buf_.size();
- memcpy(buf->data(), read_if_ready_buf_.data(), rv);
- read_if_ready_buf_.clear();
- return rv;
- }
- scoped_refptr<IOBuffer> buf_copy = base::MakeRefCounted<IOBuffer>(len);
- int rv = Read(buf_copy.get(), len,
- base::BindOnce(&FakeBlockingStreamSocket::CompleteReadIfReady,
- base::Unretained(this), buf_copy));
- if (rv > 0)
- memcpy(buf->data(), buf_copy->data(), rv);
- if (rv == ERR_IO_PENDING)
- read_if_ready_callback_ = std::move(callback);
- return rv;
- }
- int FakeBlockingStreamSocket::CancelReadIfReady() {
- DCHECK(!read_if_ready_callback_.is_null());
- read_if_ready_callback_.Reset();
- return OK;
- }
- int FakeBlockingStreamSocket::Write(
- IOBuffer* buf,
- int len,
- CompletionOnceCallback callback,
- const NetworkTrafficAnnotationTag& traffic_annotation) {
- DCHECK(buf);
- DCHECK_LE(0, len);
- if (!should_block_write_)
- return transport_->Write(buf, len, std::move(callback), traffic_annotation);
- // Schedule the write, but do nothing.
- DCHECK(!pending_write_buf_.get());
- DCHECK_EQ(-1, pending_write_len_);
- DCHECK(pending_write_callback_.is_null());
- DCHECK(!callback.is_null());
- pending_write_buf_ = buf;
- pending_write_len_ = len;
- pending_write_callback_ = std::move(callback);
- // Stop the write loop, if any.
- if (write_loop_)
- write_loop_->Quit();
- return ERR_IO_PENDING;
- }
- void FakeBlockingStreamSocket::BlockReadResult() {
- DCHECK(!should_block_read_);
- should_block_read_ = true;
- }
- void FakeBlockingStreamSocket::UnblockReadResult() {
- DCHECK(should_block_read_);
- should_block_read_ = false;
- // If the operation has since completed, return the result to the caller.
- if (pending_read_result_ != ERR_IO_PENDING)
- ReturnReadResult();
- }
- bool FakeBlockingStreamSocket::ReplaceReadResult(const std::string& data) {
- DCHECK(should_block_read_);
- DCHECK_NE(ERR_IO_PENDING, pending_read_result_);
- DCHECK(pending_read_buf_);
- DCHECK_NE(-1, pending_read_buf_len_);
- if (static_cast<size_t>(pending_read_buf_len_) < data.size())
- return false;
- memcpy(pending_read_buf_->data(), data.data(), data.size());
- pending_read_result_ = data.size();
- return true;
- }
- void FakeBlockingStreamSocket::WaitForReadResult() {
- DCHECK(should_block_read_);
- DCHECK(!read_loop_);
- if (pending_read_result_ != ERR_IO_PENDING)
- return;
- read_loop_ = std::make_unique<base::RunLoop>();
- read_loop_->Run();
- read_loop_.reset();
- DCHECK_NE(ERR_IO_PENDING, pending_read_result_);
- }
- void FakeBlockingStreamSocket::BlockWrite() {
- DCHECK(!should_block_write_);
- should_block_write_ = true;
- }
- void FakeBlockingStreamSocket::CallPendingWriteCallback(int rv) {
- std::move(pending_write_callback_).Run(rv);
- }
- void FakeBlockingStreamSocket::UnblockWrite() {
- DCHECK(should_block_write_);
- should_block_write_ = false;
- // Do nothing if UnblockWrite() was called after BlockWrite(),
- // without a Write() in between.
- if (!pending_write_buf_.get())
- return;
- int rv = transport_->Write(
- pending_write_buf_.get(), pending_write_len_,
- base::BindOnce(&FakeBlockingStreamSocket::CallPendingWriteCallback,
- base::Unretained(this)),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- pending_write_buf_ = nullptr;
- pending_write_len_ = -1;
- if (rv != ERR_IO_PENDING) {
- std::move(pending_write_callback_).Run(rv);
- }
- }
- void FakeBlockingStreamSocket::WaitForWrite() {
- DCHECK(should_block_write_);
- DCHECK(!write_loop_);
- if (pending_write_buf_.get())
- return;
- write_loop_ = std::make_unique<base::RunLoop>();
- write_loop_->Run();
- write_loop_.reset();
- DCHECK(pending_write_buf_.get());
- }
- void FakeBlockingStreamSocket::OnReadCompleted(int result) {
- DCHECK_EQ(ERR_IO_PENDING, pending_read_result_);
- DCHECK(!pending_read_callback_.is_null());
- pending_read_result_ = result;
- if (should_block_read_) {
- // Defer the result until UnblockReadResult is called.
- if (read_loop_)
- read_loop_->Quit();
- return;
- }
- ReturnReadResult();
- }
- void FakeBlockingStreamSocket::CompleteReadIfReady(scoped_refptr<IOBuffer> buf,
- int rv) {
- DCHECK(read_if_ready_buf_.empty());
- DCHECK(!should_block_read_);
- if (rv > 0)
- read_if_ready_buf_ = std::string(buf->data(), buf->data() + rv);
- // The callback may be null if CancelReadIfReady() was called.
- if (!read_if_ready_callback_.is_null())
- std::move(read_if_ready_callback_).Run(rv > 0 ? OK : rv);
- }
- void FakeBlockingStreamSocket::ReturnReadResult() {
- int result = pending_read_result_;
- pending_read_result_ = ERR_IO_PENDING;
- pending_read_buf_ = nullptr;
- pending_read_buf_len_ = -1;
- std::move(pending_read_callback_).Run(result);
- }
- // CountingStreamSocket wraps an existing StreamSocket and maintains a count of
- // reads and writes on the socket.
- class CountingStreamSocket : public WrappedStreamSocket {
- public:
- explicit CountingStreamSocket(std::unique_ptr<StreamSocket> transport)
- : WrappedStreamSocket(std::move(transport)) {}
- ~CountingStreamSocket() override = default;
- // Socket implementation:
- int Read(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override {
- read_count_++;
- return transport_->Read(buf, buf_len, std::move(callback));
- }
- int Write(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback,
- const NetworkTrafficAnnotationTag& traffic_annotation) override {
- write_count_++;
- return transport_->Write(buf, buf_len, std::move(callback),
- traffic_annotation);
- }
- int read_count() const { return read_count_; }
- int write_count() const { return write_count_; }
- private:
- int read_count_ = 0;
- int write_count_ = 0;
- };
- // A helper class that will delete |socket| when the callback is invoked.
- class DeleteSocketCallback : public TestCompletionCallbackBase {
- public:
- explicit DeleteSocketCallback(StreamSocket* socket) : socket_(socket) {}
- DeleteSocketCallback(const DeleteSocketCallback&) = delete;
- DeleteSocketCallback& operator=(const DeleteSocketCallback&) = delete;
- ~DeleteSocketCallback() override = default;
- CompletionOnceCallback callback() {
- return base::BindOnce(&DeleteSocketCallback::OnComplete,
- base::Unretained(this));
- }
- private:
- void OnComplete(int result) {
- if (socket_) {
- delete socket_;
- socket_ = nullptr;
- } else {
- ADD_FAILURE() << "Deleting socket twice";
- }
- SetResult(result);
- }
- raw_ptr<StreamSocket> socket_;
- };
- // A mock ExpectCTReporter that remembers the latest violation that was
- // reported and the number of violations reported.
- class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
- public:
- MockExpectCTReporter() = default;
- ~MockExpectCTReporter() override = default;
- void OnExpectCTFailed(
- const HostPortPair& host_port_pair,
- const GURL& report_uri,
- base::Time expiration,
- const X509Certificate* validated_certificate_chain,
- const X509Certificate* served_certificate_chain,
- const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps,
- const NetworkIsolationKey& network_isolation_key) override {
- num_failures_++;
- host_port_pair_ = host_port_pair;
- report_uri_ = report_uri;
- served_certificate_chain_ = served_certificate_chain;
- validated_certificate_chain_ = validated_certificate_chain;
- signed_certificate_timestamps_ = signed_certificate_timestamps;
- network_isolation_key_ = network_isolation_key;
- }
- const HostPortPair& host_port_pair() const { return host_port_pair_; }
- const GURL& report_uri() const { return report_uri_; }
- uint32_t num_failures() const { return num_failures_; }
- const X509Certificate* served_certificate_chain() const {
- return served_certificate_chain_;
- }
- const X509Certificate* validated_certificate_chain() const {
- return validated_certificate_chain_;
- }
- const SignedCertificateTimestampAndStatusList& signed_certificate_timestamps()
- const {
- return signed_certificate_timestamps_;
- }
- const NetworkIsolationKey network_isolation_key() const {
- return network_isolation_key_;
- }
- private:
- HostPortPair host_port_pair_;
- GURL report_uri_;
- uint32_t num_failures_ = 0;
- raw_ptr<const X509Certificate> served_certificate_chain_;
- raw_ptr<const X509Certificate> validated_certificate_chain_;
- SignedCertificateTimestampAndStatusList signed_certificate_timestamps_;
- NetworkIsolationKey network_isolation_key_;
- };
- // A mock CTVerifier that records every call to Verify but doesn't verify
- // anything.
- class MockCTVerifier : public CTVerifier {
- public:
- MOCK_METHOD6(Verify,
- void(base::StringPiece,
- X509Certificate*,
- base::StringPiece,
- base::StringPiece,
- SignedCertificateTimestampAndStatusList*,
- const NetLogWithSource&));
- };
- // A mock CTPolicyEnforcer that returns a custom verification result.
- class MockCTPolicyEnforcer : public CTPolicyEnforcer {
- public:
- MOCK_METHOD3(CheckCompliance,
- ct::CTPolicyCompliance(X509Certificate* cert,
- const ct::SCTList&,
- const NetLogWithSource&));
- };
- class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
- public:
- MOCK_METHOD3(IsCTRequiredForHost,
- CTRequirementLevel(const std::string& host,
- const X509Certificate* chain,
- const HashValueVector& hashes));
- };
- class MockSCTAuditingDelegate : public SCTAuditingDelegate {
- public:
- MOCK_METHOD(bool, IsSCTAuditingEnabled, ());
- MOCK_METHOD(void,
- MaybeEnqueueReport,
- (const net::HostPortPair&,
- const net::X509Certificate*,
- const net::SignedCertificateTimestampAndStatusList&));
- };
- class ManySmallRecordsHttpResponse : public test_server::HttpResponse {
- public:
- static std::unique_ptr<test_server::HttpResponse> HandleRequest(
- const test_server::HttpRequest& request) {
- if (request.relative_url != "/ssl-many-small-records") {
- return nullptr;
- }
- // Write ~26K of data, in 1350 byte chunks
- return std::make_unique<ManySmallRecordsHttpResponse>(/*chunk_size=*/1350,
- /*chunk_count=*/20);
- }
- ManySmallRecordsHttpResponse(size_t chunk_size, size_t chunk_count)
- : chunk_size_(chunk_size), chunk_count_(chunk_count) {}
- void SendResponse(
- base::WeakPtr<test_server::HttpResponseDelegate> delegate) override {
- base::StringPairs headers = {
- {"Connection", "close"},
- {"Content-Length", base::NumberToString(chunk_size_ * chunk_count_)},
- {"Content-Type", "text/plain"}};
- delegate->SendResponseHeaders(HTTP_OK, "OK", headers);
- SendChunks(chunk_size_, chunk_count_, delegate);
- }
- private:
- static void SendChunks(
- size_t chunk_size,
- size_t chunk_count,
- base::WeakPtr<test_server::HttpResponseDelegate> delegate) {
- if (!delegate)
- return;
- if (chunk_count == 0) {
- delegate->FinishResponse();
- return;
- }
- std::string chunk(chunk_size, '*');
- // This assumes that splitting output into separate |send| calls will
- // produce separate TLS records.
- delegate->SendContents(chunk, base::BindOnce(&SendChunks, chunk_size,
- chunk_count - 1, delegate));
- }
- size_t chunk_size_;
- size_t chunk_count_;
- };
- class SSLClientSocketTest : public PlatformTest, public WithTaskEnvironment {
- public:
- SSLClientSocketTest()
- : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
- ssl_config_service_(
- std::make_unique<TestSSLConfigService>(SSLContextConfig())),
- cert_verifier_(std::make_unique<MockCertVerifier>()),
- transport_security_state_(std::make_unique<TransportSecurityState>()),
- ct_policy_enforcer_(std::make_unique<MockCTPolicyEnforcer>()),
- ssl_client_session_cache_(std::make_unique<SSLClientSessionCache>(
- SSLClientSessionCache::Config())),
- context_(
- std::make_unique<SSLClientContext>(ssl_config_service_.get(),
- cert_verifier_.get(),
- transport_security_state_.get(),
- ct_policy_enforcer_.get(),
- ssl_client_session_cache_.get(),
- nullptr)) {
- cert_verifier_->set_default_result(OK);
- cert_verifier_->set_async(true);
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(_, _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- }
- protected:
- // The address of the test server, after calling StartEmbeddedTestServer().
- const AddressList& addr() const { return addr_; }
- // The hostname of the test server, after calling StartEmbeddedTestServer().
- const HostPortPair& host_port_pair() const { return host_port_pair_; }
- // The EmbeddedTestServer object, after calling StartEmbeddedTestServer().
- EmbeddedTestServer* embedded_test_server() {
- return embedded_test_server_.get();
- }
- // Starts the embedded test server with the specified parameters. Returns true
- // on success.
- bool StartEmbeddedTestServer(EmbeddedTestServer::ServerCertificate cert,
- const SSLServerConfig& server_config) {
- embedded_test_server_ =
- std::make_unique<EmbeddedTestServer>(EmbeddedTestServer::TYPE_HTTPS);
- embedded_test_server_->SetSSLConfig(cert, server_config);
- return FinishStartingEmbeddedTestServer();
- }
- // Starts the embedded test server with the specified parameters. Returns true
- // on success.
- bool StartEmbeddedTestServer(
- const EmbeddedTestServer::ServerCertificateConfig& cert_config,
- const SSLServerConfig& server_config) {
- embedded_test_server_ =
- std::make_unique<EmbeddedTestServer>(EmbeddedTestServer::TYPE_HTTPS);
- embedded_test_server_->SetSSLConfig(cert_config, server_config);
- return FinishStartingEmbeddedTestServer();
- }
- bool FinishStartingEmbeddedTestServer() {
- RegisterEmbeddedTestServerHandlers(embedded_test_server_.get());
- if (!embedded_test_server_->Start()) {
- LOG(ERROR) << "Could not start EmbeddedTestServer";
- return false;
- }
- if (!embedded_test_server_->GetAddressList(&addr_)) {
- LOG(ERROR) << "Could not get EmbeddedTestServer address list";
- return false;
- }
- host_port_pair_ = embedded_test_server_->host_port_pair();
- return true;
- }
- // May be overridden by the subclass to customize the EmbeddedTestServer.
- virtual void RegisterEmbeddedTestServerHandlers(EmbeddedTestServer* server) {
- server->AddDefaultHandlers(base::FilePath());
- server->RegisterRequestHandler(
- base::BindRepeating(&ManySmallRecordsHttpResponse::HandleRequest));
- server->RegisterRequestHandler(
- base::BindRepeating(&HandleSSLInfoRequest, base::Unretained(this)));
- }
- std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
- std::unique_ptr<StreamSocket> transport_socket,
- const HostPortPair& host_and_port,
- const SSLConfig& ssl_config) {
- return socket_factory_->CreateSSLClientSocket(
- context_.get(), std::move(transport_socket), host_and_port, ssl_config);
- }
- // Create an SSLClientSocket object and use it to connect to a test server,
- // then wait for connection results. This must be called after a successful
- // StartEmbeddedTestServer() call.
- //
- // |ssl_config| The SSL configuration to use.
- // |host_port_pair| The hostname and port to use at the SSL layer. (The
- // socket connection will still be made to |embedded_test_server_|.)
- // |result| will retrieve the ::Connect() result value.
- //
- // Returns true on success, false otherwise. Success means that the SSL
- // socket could be created and its Connect() was called, not that the
- // connection itself was a success.
- bool CreateAndConnectSSLClientSocketWithHost(
- const SSLConfig& ssl_config,
- const HostPortPair& host_port_pair,
- int* result) {
- auto transport = std::make_unique<TCPClientSocket>(
- addr_, nullptr, nullptr, NetLog::Get(), NetLogSource());
- int rv = callback_.GetResult(transport->Connect(callback_.callback()));
- if (rv != OK) {
- LOG(ERROR) << "Could not connect to test server";
- return false;
- }
- sock_ =
- CreateSSLClientSocket(std::move(transport), host_port_pair, ssl_config);
- EXPECT_FALSE(sock_->IsConnected());
- *result = callback_.GetResult(sock_->Connect(callback_.callback()));
- return true;
- }
- bool CreateAndConnectSSLClientSocket(const SSLConfig& ssl_config,
- int* result) {
- return CreateAndConnectSSLClientSocketWithHost(ssl_config, host_port_pair(),
- result);
- }
- // Adds the server certificate with provided cert status.
- // Must be called after StartEmbeddedTestServer has been called.
- void AddServerCertStatusToSSLConfig(CertStatus status,
- SSLConfig* ssl_config) {
- ASSERT_TRUE(embedded_test_server());
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- CertVerifyResult verify_result;
- verify_result.cert_status = status;
- verify_result.verified_cert = server_cert;
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- }
- absl::optional<SSLInfo> LastSSLInfoFromServer() {
- // EmbeddedTestServer callbacks run on another thread, so protect this
- // with a lock.
- base::AutoLock lock(server_ssl_info_lock_);
- auto result = server_ssl_info_;
- server_ssl_info_ = absl::nullopt;
- return result;
- }
- RecordingNetLogObserver log_observer_;
- raw_ptr<ClientSocketFactory> socket_factory_;
- std::unique_ptr<TestSSLConfigService> ssl_config_service_;
- std::unique_ptr<MockCertVerifier> cert_verifier_;
- std::unique_ptr<TransportSecurityState> transport_security_state_;
- std::unique_ptr<MockCTPolicyEnforcer> ct_policy_enforcer_;
- std::unique_ptr<SSLClientSessionCache> ssl_client_session_cache_;
- std::unique_ptr<SSLClientContext> context_;
- std::unique_ptr<SSLClientSocket> sock_;
- private:
- static std::unique_ptr<test_server::HttpResponse> HandleSSLInfoRequest(
- SSLClientSocketTest* test,
- const test_server::HttpRequest& request) {
- if (request.relative_url != "/ssl-info") {
- return nullptr;
- }
- {
- // EmbeddedTestServer callbacks run on another thread, so protect this
- // with a lock.
- base::AutoLock lock(test->server_ssl_info_lock_);
- test->server_ssl_info_ = request.ssl_info;
- }
- return std::make_unique<test_server::BasicHttpResponse>();
- }
- std::unique_ptr<EmbeddedTestServer> embedded_test_server_;
- base::Lock server_ssl_info_lock_;
- absl::optional<SSLInfo> server_ssl_info_ GUARDED_BY(server_ssl_info_lock_);
- TestCompletionCallback callback_;
- AddressList addr_;
- HostPortPair host_port_pair_;
- };
- enum ReadIfReadyTransport {
- // ReadIfReady() is implemented by the underlying transport.
- READ_IF_READY_SUPPORTED,
- // ReadIfReady() is not implemented by the underlying transport.
- READ_IF_READY_NOT_SUPPORTED,
- };
- enum ReadIfReadySSL {
- // Test reads by calling ReadIfReady() on the SSL socket.
- TEST_SSL_READ_IF_READY,
- // Test reads by calling Read() on the SSL socket.
- TEST_SSL_READ,
- };
- class StreamSocketWithoutReadIfReady : public WrappedStreamSocket {
- public:
- explicit StreamSocketWithoutReadIfReady(
- std::unique_ptr<StreamSocket> transport)
- : WrappedStreamSocket(std::move(transport)) {}
- int ReadIfReady(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override {
- return ERR_READ_IF_READY_NOT_IMPLEMENTED;
- }
- int CancelReadIfReady() override { return ERR_READ_IF_READY_NOT_IMPLEMENTED; }
- };
- class ClientSocketFactoryWithoutReadIfReady : public ClientSocketFactory {
- public:
- explicit ClientSocketFactoryWithoutReadIfReady(ClientSocketFactory* factory)
- : factory_(factory) {}
- std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
- DatagramSocket::BindType bind_type,
- NetLog* net_log,
- const NetLogSource& source) override {
- return factory_->CreateDatagramClientSocket(bind_type, net_log, source);
- }
- std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
- const AddressList& addresses,
- std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
- NetworkQualityEstimator* network_quality_estimator,
- NetLog* net_log,
- const NetLogSource& source) override {
- return factory_->CreateTransportClientSocket(
- addresses, std::move(socket_performance_watcher),
- network_quality_estimator, net_log, source);
- }
- std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
- SSLClientContext* context,
- std::unique_ptr<StreamSocket> stream_socket,
- const HostPortPair& host_and_port,
- const SSLConfig& ssl_config) override {
- stream_socket = std::make_unique<StreamSocketWithoutReadIfReady>(
- std::move(stream_socket));
- return factory_->CreateSSLClientSocket(context, std::move(stream_socket),
- host_and_port, ssl_config);
- }
- private:
- const raw_ptr<ClientSocketFactory> factory_;
- };
- std::vector<uint16_t> GetTLSVersions() {
- return {SSL_PROTOCOL_VERSION_TLS1_2, SSL_PROTOCOL_VERSION_TLS1_3};
- }
- class SSLClientSocketVersionTest
- : public SSLClientSocketTest,
- public ::testing::WithParamInterface<uint16_t> {
- protected:
- SSLClientSocketVersionTest() = default;
- uint16_t version() const { return GetParam(); }
- SSLServerConfig GetServerConfig() {
- SSLServerConfig config;
- config.version_max = version();
- config.version_min = version();
- return config;
- }
- };
- // If GetParam(), try ReadIfReady() and fall back to Read() if needed.
- class SSLClientSocketReadTest
- : public SSLClientSocketTest,
- public ::testing::WithParamInterface<
- std::tuple<ReadIfReadyTransport, ReadIfReadySSL, uint16_t>> {
- protected:
- SSLClientSocketReadTest() : SSLClientSocketTest() {
- if (!read_if_ready_supported()) {
- wrapped_socket_factory_ =
- std::make_unique<ClientSocketFactoryWithoutReadIfReady>(
- socket_factory_);
- socket_factory_ = wrapped_socket_factory_.get();
- }
- }
- // Convienient wrapper to call Read()/ReadIfReady() depending on whether
- // ReadyIfReady() is enabled.
- int Read(StreamSocket* socket,
- IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) {
- if (test_ssl_read_if_ready())
- return socket->ReadIfReady(buf, buf_len, std::move(callback));
- return socket->Read(buf, buf_len, std::move(callback));
- }
- // Wait for Read()/ReadIfReady() to complete.
- int WaitForReadCompletion(StreamSocket* socket,
- IOBuffer* buf,
- int buf_len,
- TestCompletionCallback* callback,
- int rv) {
- if (!test_ssl_read_if_ready())
- return callback->GetResult(rv);
- while (rv == ERR_IO_PENDING) {
- rv = callback->GetResult(rv);
- if (rv != OK)
- return rv;
- rv = socket->ReadIfReady(buf, buf_len, callback->callback());
- }
- return rv;
- }
- // Calls Read()/ReadIfReady() and waits for it to return data.
- int ReadAndWaitForCompletion(StreamSocket* socket,
- IOBuffer* buf,
- int buf_len) {
- TestCompletionCallback callback;
- int rv = Read(socket, buf, buf_len, callback.callback());
- return WaitForReadCompletion(socket, buf, buf_len, &callback, rv);
- }
- SSLServerConfig GetServerConfig() {
- SSLServerConfig config;
- config.version_max = version();
- config.version_min = version();
- return config;
- }
- bool test_ssl_read_if_ready() const {
- return std::get<1>(GetParam()) == TEST_SSL_READ_IF_READY;
- }
- bool read_if_ready_supported() const {
- return std::get<0>(GetParam()) == READ_IF_READY_SUPPORTED;
- }
- uint16_t version() const { return std::get<2>(GetParam()); }
- private:
- std::unique_ptr<ClientSocketFactory> wrapped_socket_factory_;
- };
- INSTANTIATE_TEST_SUITE_P(All,
- SSLClientSocketReadTest,
- Combine(Values(READ_IF_READY_SUPPORTED,
- READ_IF_READY_NOT_SUPPORTED),
- Values(TEST_SSL_READ_IF_READY, TEST_SSL_READ),
- ValuesIn(GetTLSVersions())));
- // Verifies the correctness of GetSSLCertRequestInfo.
- class SSLClientSocketCertRequestInfoTest : public SSLClientSocketVersionTest {
- protected:
- // Connects to the test server and returns the SSLCertRequestInfo reported by
- // the socket.
- scoped_refptr<SSLCertRequestInfo> GetCertRequest() {
- int rv;
- if (!CreateAndConnectSSLClientSocket(SSLConfig(), &rv)) {
- return nullptr;
- }
- EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
- auto request_info = base::MakeRefCounted<SSLCertRequestInfo>();
- sock_->GetSSLCertRequestInfo(request_info.get());
- sock_->Disconnect();
- EXPECT_FALSE(sock_->IsConnected());
- EXPECT_TRUE(host_port_pair().Equals(request_info->host_and_port));
- return request_info;
- }
- };
- class SSLClientSocketFalseStartTest : public SSLClientSocketTest {
- protected:
- // Creates an SSLClientSocket with |client_config| attached to a
- // FakeBlockingStreamSocket, returning both in |*out_raw_transport| and
- // |*out_sock|. The FakeBlockingStreamSocket is owned by the SSLClientSocket,
- // so |*out_raw_transport| is a raw pointer.
- //
- // The client socket will begin a connect using |callback| but stop before the
- // server's finished message is received. The finished message will be blocked
- // in |*out_raw_transport|. To complete the handshake and successfully read
- // data, the caller must unblock reads on |*out_raw_transport|. (Note that, if
- // the client successfully false started, |callback.WaitForResult()| will
- // return OK without unblocking transport reads. But Read() will still block.)
- //
- // Must be called after StartEmbeddedTestServer is called.
- void CreateAndConnectUntilServerFinishedReceived(
- const SSLConfig& client_config,
- TestCompletionCallback* callback,
- FakeBlockingStreamSocket** out_raw_transport,
- std::unique_ptr<SSLClientSocket>* out_sock) {
- CHECK(embedded_test_server());
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- int rv = callback->GetResult(transport->Connect(callback->callback()));
- EXPECT_THAT(rv, IsOk());
- FakeBlockingStreamSocket* raw_transport = transport.get();
- std::unique_ptr<SSLClientSocket> sock = CreateSSLClientSocket(
- std::move(transport), host_port_pair(), client_config);
- // Connect. Stop before the client processes the first server leg
- // (ServerHello, etc.)
- raw_transport->BlockReadResult();
- rv = sock->Connect(callback->callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->WaitForReadResult();
- // Release the ServerHello and wait for the client to write
- // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the
- // server's leg to complete, since it may span multiple reads.)
- EXPECT_FALSE(callback->have_result());
- raw_transport->BlockWrite();
- raw_transport->UnblockReadResult();
- raw_transport->WaitForWrite();
- // And, finally, release that and block the next server leg
- // (ChangeCipherSpec, Finished).
- raw_transport->BlockReadResult();
- raw_transport->UnblockWrite();
- *out_raw_transport = raw_transport;
- *out_sock = std::move(sock);
- }
- void TestFalseStart(const SSLServerConfig& server_config,
- const SSLConfig& client_config,
- bool expect_false_start) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- TestCompletionCallback callback;
- FakeBlockingStreamSocket* raw_transport = nullptr;
- std::unique_ptr<SSLClientSocket> sock;
- ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
- client_config, &callback, &raw_transport, &sock));
- if (expect_false_start) {
- // When False Starting, the handshake should complete before receiving the
- // Change Cipher Spec and Finished messages.
- //
- // Note: callback.have_result() may not be true without waiting. The NSS
- // state machine sometimes lives on a separate thread, so this thread may
- // not yet have processed the signal that the handshake has completed.
- int rv = callback.WaitForResult();
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- static const int kRequestTextSize =
- static_cast<int>(std::size(request_text) - 1);
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(kRequestTextSize);
- memcpy(request_buffer->data(), request_text, kRequestTextSize);
- // Write the request.
- rv = callback.GetResult(sock->Write(request_buffer.get(),
- kRequestTextSize, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(kRequestTextSize, rv);
- // The read will hang; it's waiting for the peer to complete the
- // handshake, and the handshake is still blocked.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- rv = sock->Read(buf.get(), 4096, callback.callback());
- // After releasing reads, the connection proceeds.
- raw_transport->UnblockReadResult();
- rv = callback.GetResult(rv);
- EXPECT_LT(0, rv);
- } else {
- // False Start is not enabled, so the handshake will not complete because
- // the server second leg is blocked.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(callback.have_result());
- }
- }
- };
- // Sends an HTTP request on the socket and reads the response. This may be used
- // to ensure some data has been consumed from the server.
- int MakeHTTPRequest(StreamSocket* socket, const char* path = "/") {
- std::string request = base::StringPrintf("GET %s HTTP/1.0\r\n\r\n", path);
- TestCompletionCallback callback;
- while (!request.empty()) {
- auto request_buffer =
- base::MakeRefCounted<StringIOBuffer>(std::string(request));
- int rv = callback.GetResult(
- socket->Write(request_buffer.get(), request_buffer->size(),
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- if (rv < 0) {
- return rv;
- }
- request = request.substr(rv);
- }
- auto response_buffer = base::MakeRefCounted<IOBuffer>(1024);
- int rv = callback.GetResult(
- socket->Read(response_buffer.get(), 1024, callback.callback()));
- if (rv < 0) {
- return rv;
- }
- return OK;
- }
- // Provides a response to the 0RTT request indicating whether it was received
- // as early data.
- class ZeroRTTResponse : public test_server::HttpResponse {
- public:
- explicit ZeroRTTResponse(bool zero_rtt) : zero_rtt_(zero_rtt) {}
- ZeroRTTResponse(const ZeroRTTResponse&) = delete;
- ZeroRTTResponse& operator=(const ZeroRTTResponse&) = delete;
- ~ZeroRTTResponse() override = default;
- void SendResponse(
- base::WeakPtr<test_server::HttpResponseDelegate> delegate) override {
- std::string response;
- if (zero_rtt_) {
- response = "1";
- } else {
- response = "0";
- }
- // Since the EmbeddedTestServer doesn't keep the socket open by default, it
- // is explicitly kept alive to allow the remaining leg of the 0RTT handshake
- // to be received after the early data.
- delegate->SendContents(response);
- }
- private:
- bool zero_rtt_;
- };
- std::unique_ptr<test_server::HttpResponse> HandleZeroRTTRequest(
- const test_server::HttpRequest& request) {
- if (request.GetURL().path() != "/zerortt" || !request.ssl_info)
- return nullptr;
- return std::make_unique<ZeroRTTResponse>(
- request.ssl_info->early_data_received);
- }
- class SSLClientSocketZeroRTTTest : public SSLClientSocketTest {
- protected:
- SSLClientSocketZeroRTTTest() : SSLClientSocketTest() {
- SSLContextConfig config;
- config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
- ssl_config_service_->UpdateSSLConfigAndNotify(config);
- }
- bool StartServer() {
- SSLServerConfig server_config;
- server_config.early_data_enabled = true;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
- return StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config);
- }
- void RegisterEmbeddedTestServerHandlers(EmbeddedTestServer* server) override {
- SSLClientSocketTest::RegisterEmbeddedTestServerHandlers(server);
- server->RegisterRequestHandler(base::BindRepeating(&HandleZeroRTTRequest));
- }
- void SetServerConfig(SSLServerConfig server_config) {
- embedded_test_server()->ResetSSLConfig(net::EmbeddedTestServer::CERT_OK,
- server_config);
- }
- // Makes a new connection to the test server and returns a
- // FakeBlockingStreamSocket which may be used to block transport I/O.
- //
- // Most tests should call BlockReadResult() before calling Connect(). This
- // avoid race conditions by controlling the order of events. 0-RTT typically
- // races the ServerHello from the server with early data from the client. If
- // the ServerHello arrives before client calls Write(), the data may be sent
- // with 1-RTT keys rather than 0-RTT keys.
- FakeBlockingStreamSocket* MakeClient(bool early_data_enabled) {
- SSLConfig ssl_config;
- ssl_config.early_data_enabled = early_data_enabled;
- real_transport_ = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport_));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback_.GetResult(transport->Connect(callback_.callback()));
- EXPECT_THAT(rv, IsOk());
- ssl_socket_ = CreateSSLClientSocket(std::move(transport), host_port_pair(),
- ssl_config);
- EXPECT_FALSE(ssl_socket_->IsConnected());
- return raw_transport;
- }
- int Connect() {
- return callback_.GetResult(ssl_socket_->Connect(callback_.callback()));
- }
- int WriteAndWait(base::StringPiece request) {
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(request.size());
- memcpy(request_buffer->data(), request.data(), request.size());
- return callback_.GetResult(
- ssl_socket_->Write(request_buffer.get(), request.size(),
- callback_.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- }
- int ReadAndWait(IOBuffer* buf, size_t len) {
- return callback_.GetResult(
- ssl_socket_->Read(buf, len, callback_.callback()));
- }
- bool GetSSLInfo(SSLInfo* ssl_info) {
- return ssl_socket_->GetSSLInfo(ssl_info);
- }
- bool RunInitialConnection() {
- if (MakeClient(true) == nullptr)
- return false;
- EXPECT_THAT(Connect(), IsOk());
- // Use the socket for an HTTP request to ensure we've processed the
- // post-handshake TLS 1.3 ticket.
- EXPECT_THAT(MakeHTTPRequest(ssl_socket_.get()), IsOk());
- SSLInfo ssl_info;
- EXPECT_TRUE(GetSSLInfo(&ssl_info));
- // Make sure all asynchronous histogram logging is complete.
- base::RunLoop().RunUntilIdle();
- return SSLInfo::HANDSHAKE_FULL == ssl_info.handshake_type;
- }
- SSLClientSocket* ssl_socket() { return ssl_socket_.get(); }
- private:
- TestCompletionCallback callback_;
- std::unique_ptr<StreamSocket> real_transport_;
- std::unique_ptr<SSLClientSocket> ssl_socket_;
- };
- // Returns a serialized unencrypted TLS 1.2 alert record for the given alert
- // value.
- std::string FormatTLS12Alert(uint8_t alert) {
- std::string ret;
- // ContentType.alert
- ret.push_back(21);
- // Record-layer version. Assume TLS 1.2.
- ret.push_back(0x03);
- ret.push_back(0x03);
- // Record length.
- ret.push_back(0);
- ret.push_back(2);
- // AlertLevel.fatal.
- ret.push_back(2);
- // The alert itself.
- ret.push_back(alert);
- return ret;
- }
- // A CertVerifier that never returns on any requests.
- class HangingCertVerifier : public CertVerifier {
- public:
- int num_active_requests() const { return num_active_requests_; }
- void WaitForRequest() {
- if (!num_active_requests_) {
- run_loop_.Run();
- }
- }
- int Verify(const RequestParams& params,
- CertVerifyResult* verify_result,
- CompletionOnceCallback callback,
- std::unique_ptr<Request>* out_req,
- const NetLogWithSource& net_log) override {
- *out_req = std::make_unique<HangingRequest>(this);
- return ERR_IO_PENDING;
- }
- void SetConfig(const Config& config) override {}
- private:
- class HangingRequest : public Request {
- public:
- explicit HangingRequest(HangingCertVerifier* verifier)
- : verifier_(verifier) {
- verifier_->num_active_requests_++;
- verifier_->run_loop_.Quit();
- }
- ~HangingRequest() override { verifier_->num_active_requests_--; }
- private:
- raw_ptr<HangingCertVerifier> verifier_;
- };
- base::RunLoop run_loop_;
- int num_active_requests_ = 0;
- };
- } // namespace
- INSTANTIATE_TEST_SUITE_P(TLSVersion,
- SSLClientSocketVersionTest,
- ValuesIn(GetTLSVersions()));
- TEST_P(SSLClientSocketVersionTest, Connect) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, NetLog::Get(), NetLogSource());
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- EXPECT_FALSE(sock->IsConnected());
- rv = sock->Connect(callback.callback());
- auto entries = log_observer_.GetEntries();
- EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLogEventType::SSL_CONNECT));
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- entries = log_observer_.GetEntries();
- EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT));
- sock->Disconnect();
- EXPECT_FALSE(sock->IsConnected());
- }
- TEST_P(SSLClientSocketVersionTest, ConnectSyncVerify) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- cert_verifier_->set_async(false);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(OK));
- }
- TEST_P(SSLClientSocketVersionTest, ConnectExpired) {
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_EXPIRED,
- GetServerConfig()));
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_CERT_DATE_INVALID));
- // Rather than testing whether or not the underlying socket is connected,
- // test that the handshake has finished. This is because it may be
- // desirable to disconnect the socket before showing a user prompt, since
- // the user may take indefinitely long to respond.
- auto entries = log_observer_.GetEntries();
- EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT));
- }
- TEST_P(SSLClientSocketVersionTest, ConnectExpiredSyncVerify) {
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_EXPIRED,
- GetServerConfig()));
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- cert_verifier_->set_async(false);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_CERT_DATE_INVALID));
- }
- // Test that SSLClientSockets may be destroyed while waiting on a certificate
- // verification.
- TEST_P(SSLClientSocketVersionTest, SocketDestroyedDuringVerify) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- HangingCertVerifier verifier;
- context_ = std::make_unique<SSLClientContext>(
- ssl_config_service_.get(), &verifier, transport_security_state_.get(),
- ct_policy_enforcer_.get(), ssl_client_session_cache_.get(), nullptr);
- TestCompletionCallback callback;
- auto transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, NetLog::Get(), NetLogSource());
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock = CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig());
- rv = sock->Connect(callback.callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- // The socket should attempt a certificate verification.
- verifier.WaitForRequest();
- EXPECT_EQ(1, verifier.num_active_requests());
- // Destroying the socket should cancel it.
- sock = nullptr;
- EXPECT_EQ(0, verifier.num_active_requests());
- context_ = nullptr;
- }
- TEST_P(SSLClientSocketVersionTest, ConnectMismatched) {
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_MISMATCHED_NAME,
- GetServerConfig()));
- cert_verifier_->set_default_result(ERR_CERT_COMMON_NAME_INVALID);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_CERT_COMMON_NAME_INVALID));
- // Rather than testing whether or not the underlying socket is connected,
- // test that the handshake has finished. This is because it may be
- // desirable to disconnect the socket before showing a user prompt, since
- // the user may take indefinitely long to respond.
- auto entries = log_observer_.GetEntries();
- EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT));
- }
- // Tests that certificates parsable by SSLClientSocket's internal SSL
- // implementation, but not X509Certificate are treated as fatal connection
- // errors. This is a regression test for https://crbug.com/91341.
- TEST_P(SSLClientSocketVersionTest, ConnectBadValidity) {
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_BAD_VALIDITY,
- GetServerConfig()));
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- EXPECT_THAT(rv, IsError(ERR_CERT_DATE_INVALID));
- }
- // Ignoring the certificate error from an invalid certificate should
- // allow a complete connection.
- TEST_P(SSLClientSocketVersionTest, ConnectBadValidityIgnoreCertErrors) {
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_BAD_VALIDITY,
- GetServerConfig()));
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- SSLConfig ssl_config;
- ssl_config.ignore_certificate_errors = true;
- int rv;
- CreateAndConnectSSLClientSocket(ssl_config, &rv);
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- }
- // Attempt to connect to a page which requests a client certificate. It should
- // return an error code on connect.
- TEST_P(SSLClientSocketVersionTest, ConnectClientAuthCertRequested) {
- SSLServerConfig server_config = GetServerConfig();
- server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
- auto entries = log_observer_.GetEntries();
- EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT));
- EXPECT_FALSE(sock_->IsConnected());
- }
- // Connect to a server requesting optional client authentication. Send it a
- // null certificate. It should allow the connection.
- TEST_P(SSLClientSocketVersionTest, ConnectClientAuthSendNullCert) {
- SSLServerConfig server_config = GetServerConfig();
- server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // Our test server accepts certificate-less connections.
- context_->SetClientCertificate(host_port_pair(), nullptr, nullptr);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- // We responded to the server's certificate request with a Certificate
- // message with no client certificate in it. ssl_info.client_cert_sent
- // should be false in this case.
- SSLInfo ssl_info;
- sock_->GetSSLInfo(&ssl_info);
- EXPECT_FALSE(ssl_info.client_cert_sent);
- sock_->Disconnect();
- EXPECT_FALSE(sock_->IsConnected());
- }
- // TODO(wtc): Add unit tests for IsConnectedAndIdle:
- // - Server closes an SSL connection (with a close_notify alert message).
- // - Server closes the underlying TCP connection directly.
- // - Server sends data unexpectedly.
- // Tests that the socket can be read from successfully. Also test that a peer's
- // close_notify alert is successfully processed without error.
- TEST_P(SSLClientSocketReadTest, Read) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto transport = std::make_unique<TCPClientSocket>(addr(), nullptr, nullptr,
- nullptr, NetLogSource());
- EXPECT_EQ(0, transport->GetTotalReceivedBytes());
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- EXPECT_EQ(0, sock->GetTotalReceivedBytes());
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- // Number of network bytes received should increase because of SSL socket
- // establishment.
- EXPECT_GT(sock->GetTotalReceivedBytes(), 0);
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(std::size(request_text) - 1);
- memcpy(request_buffer->data(), request_text, std::size(request_text) - 1);
- rv = callback.GetResult(
- sock->Write(request_buffer.get(), std::size(request_text) - 1,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(static_cast<int>(std::size(request_text) - 1), rv);
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int64_t unencrypted_bytes_read = 0;
- int64_t network_bytes_read_during_handshake = sock->GetTotalReceivedBytes();
- do {
- rv = ReadAndWaitForCompletion(sock.get(), buf.get(), 4096);
- EXPECT_GE(rv, 0);
- if (rv >= 0) {
- unencrypted_bytes_read += rv;
- }
- } while (rv > 0);
- EXPECT_GT(unencrypted_bytes_read, 0);
- // Reading the payload should increase the number of bytes on network layer.
- EXPECT_GT(sock->GetTotalReceivedBytes(), network_bytes_read_during_handshake);
- // Number of bytes received on the network after the handshake should be
- // higher than the number of encrypted bytes read.
- EXPECT_GE(sock->GetTotalReceivedBytes() - network_bytes_read_during_handshake,
- unencrypted_bytes_read);
- // The peer should have cleanly closed the connection with a close_notify.
- EXPECT_EQ(0, rv);
- }
- // Tests that SSLClientSocket properly handles when the underlying transport
- // synchronously fails a transport write in during the handshake.
- TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- SynchronousErrorStreamSocket* raw_transport = transport.get();
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- raw_transport->SetNextWriteError(ERR_CONNECTION_RESET);
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
- EXPECT_FALSE(sock->IsConnected());
- }
- // Tests that the SSLClientSocket properly handles when the underlying transport
- // synchronously returns an error code - such as if an intermediary terminates
- // the socket connection uncleanly.
- // This is a regression test for http://crbug.com/238536
- TEST_P(SSLClientSocketReadTest, Read_WithSynchronousError) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- SSLConfig config;
- config.disable_post_handshake_peek_for_testing = true;
- SynchronousErrorStreamSocket* raw_transport = transport.get();
- std::unique_ptr<SSLClientSocket> sock(
- CreateSSLClientSocket(std::move(transport), host_port_pair(), config));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- static const int kRequestTextSize =
- static_cast<int>(std::size(request_text) - 1);
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(kRequestTextSize);
- memcpy(request_buffer->data(), request_text, kRequestTextSize);
- rv = callback.GetResult(sock->Write(request_buffer.get(), kRequestTextSize,
- callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(kRequestTextSize, rv);
- // Simulate an unclean/forcible shutdown.
- raw_transport->SetNextReadError(ERR_CONNECTION_RESET);
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- // Note: This test will hang if this bug has regressed. Simply checking that
- // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate
- // result when using a dedicated task runner for NSS.
- rv = ReadAndWaitForCompletion(sock.get(), buf.get(), 4096);
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
- }
- // Tests that the SSLClientSocket properly handles when the underlying transport
- // asynchronously returns an error code while writing data - such as if an
- // intermediary terminates the socket connection uncleanly.
- // This is a regression test for http://crbug.com/249848
- TEST_P(SSLClientSocketVersionTest, Write_WithSynchronousError) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- // Note: |error_socket|'s ownership is handed to |transport|, but a pointer
- // is retained in order to configure additional errors.
- auto error_socket =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(error_socket));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- static const int kRequestTextSize =
- static_cast<int>(std::size(request_text) - 1);
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(kRequestTextSize);
- memcpy(request_buffer->data(), request_text, kRequestTextSize);
- // Simulate an unclean/forcible shutdown on the underlying socket.
- // However, simulate this error asynchronously.
- raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
- raw_transport->BlockWrite();
- // This write should complete synchronously, because the TLS ciphertext
- // can be created and placed into the outgoing buffers independent of the
- // underlying transport.
- rv = callback.GetResult(sock->Write(request_buffer.get(), kRequestTextSize,
- callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(kRequestTextSize, rv);
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- rv = sock->Read(buf.get(), 4096, callback.callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- // Now unblock the outgoing request, having it fail with the connection
- // being reset.
- raw_transport->UnblockWrite();
- // Note: This will cause an inifite loop if this bug has regressed. Simply
- // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING
- // is a legitimate result when using a dedicated task runner for NSS.
- rv = callback.GetResult(rv);
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
- }
- // If there is a Write failure at the transport with no follow-up Read, although
- // the write error will not be returned to the client until a future Read or
- // Write operation, SSLClientSocket should not spin attempting to re-write on
- // the socket. This is a regression test for part of https://crbug.com/381160.
- TEST_P(SSLClientSocketVersionTest, Write_WithSynchronousErrorNoRead) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- // Note: intermediate sockets' ownership are handed to |sock|, but a pointer
- // is retained in order to query them.
- auto error_socket =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
- auto counting_socket =
- std::make_unique<CountingStreamSocket>(std::move(error_socket));
- CountingStreamSocket* raw_counting_socket = counting_socket.get();
- int rv = callback.GetResult(counting_socket->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(counting_socket), host_port_pair(), SSLConfig()));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock->IsConnected());
- // Simulate an unclean/forcible shutdown on the underlying socket.
- raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- static const int kRequestTextSize =
- static_cast<int>(std::size(request_text) - 1);
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(kRequestTextSize);
- memcpy(request_buffer->data(), request_text, kRequestTextSize);
- // This write should complete synchronously, because the TLS ciphertext
- // can be created and placed into the outgoing buffers independent of the
- // underlying transport.
- rv = callback.GetResult(sock->Write(request_buffer.get(), kRequestTextSize,
- callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- ASSERT_EQ(kRequestTextSize, rv);
- // Let the event loop spin for a little bit of time. Even on platforms where
- // pumping the state machine involve thread hops, there should be no further
- // writes on the transport socket.
- //
- // TODO(davidben): Avoid the arbitrary timeout?
- int old_write_count = raw_counting_socket->write_count();
- base::RunLoop loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, loop.QuitClosure(), base::Milliseconds(100));
- loop.Run();
- EXPECT_EQ(old_write_count, raw_counting_socket->write_count());
- }
- // Test the full duplex mode, with Read and Write pending at the same time.
- // This test also serves as a regression test for http://crbug.com/29815.
- TEST_P(SSLClientSocketReadTest, Read_FullDuplex) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- // Issue a "hanging" Read first.
- TestCompletionCallback callback;
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int read_rv = Read(sock_.get(), buf.get(), 4096, callback.callback());
- // We haven't written the request, so there should be no response yet.
- ASSERT_THAT(read_rv, IsError(ERR_IO_PENDING));
- // Write the request.
- // The request is padded with a User-Agent header to a size that causes the
- // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around.
- // This tests the fix for http://crbug.com/29815.
- std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
- for (int i = 0; i < 3770; ++i)
- request_text.push_back('*');
- request_text.append("\r\n\r\n");
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<StringIOBuffer>(request_text);
- TestCompletionCallback callback2; // Used for Write only.
- rv = callback2.GetResult(
- sock_->Write(request_buffer.get(), request_text.size(),
- callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(static_cast<int>(request_text.size()), rv);
- // Now get the Read result.
- read_rv =
- WaitForReadCompletion(sock_.get(), buf.get(), 4096, &callback, read_rv);
- EXPECT_GT(read_rv, 0);
- }
- // Attempts to Read() and Write() from an SSLClientSocketNSS in full duplex
- // mode when the underlying transport is blocked on sending data. When the
- // underlying transport completes due to an error, it should invoke both the
- // Read() and Write() callbacks. If the socket is deleted by the Read()
- // callback, the Write() callback should not be invoked.
- // Regression test for http://crbug.com/232633
- TEST_P(SSLClientSocketReadTest, Read_DeleteWhilePendingFullDuplex) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- // Note: |error_socket|'s ownership is handed to |transport|, but a pointer
- // is retained in order to configure additional errors.
- auto error_socket =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(error_socket));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- SSLConfig config;
- config.disable_post_handshake_peek_for_testing = true;
- std::unique_ptr<SSLClientSocket> sock =
- CreateSSLClientSocket(std::move(transport), host_port_pair(), config);
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
- request_text.append(20 * 1024, '*');
- request_text.append("\r\n\r\n");
- scoped_refptr<DrainableIOBuffer> request_buffer =
- base::MakeRefCounted<DrainableIOBuffer>(
- base::MakeRefCounted<StringIOBuffer>(request_text),
- request_text.size());
- // Simulate errors being returned from the underlying Read() and Write() ...
- raw_error_socket->SetNextReadError(ERR_CONNECTION_RESET);
- raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
- // ... but have those errors returned asynchronously. Because the Write() will
- // return first, this will trigger the error.
- raw_transport->BlockReadResult();
- raw_transport->BlockWrite();
- // Enqueue a Read() before calling Write(), which should "hang" due to
- // the ERR_IO_PENDING caused by SetReadShouldBlock() and thus return.
- SSLClientSocket* raw_sock = sock.get();
- DeleteSocketCallback read_callback(sock.release());
- scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(4096);
- rv = Read(raw_sock, read_buf.get(), 4096, read_callback.callback());
- // Ensure things didn't complete synchronously, otherwise |sock| is invalid.
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- ASSERT_FALSE(read_callback.have_result());
- // Attempt to write the remaining data. OpenSSL will return that its blocked
- // because the underlying transport is blocked.
- rv = raw_sock->Write(request_buffer.get(), request_buffer->BytesRemaining(),
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- ASSERT_FALSE(callback.have_result());
- // Now unblock Write(), which will invoke OnSendComplete and (eventually)
- // call the Read() callback, deleting the socket and thus aborting calling
- // the Write() callback.
- raw_transport->UnblockWrite();
- // |read_callback| deletes |sock| so if ReadIfReady() is used, we will get OK
- // asynchronously but can't continue reading because the socket is gone.
- rv = read_callback.WaitForResult();
- if (test_ssl_read_if_ready()) {
- EXPECT_THAT(rv, IsOk());
- } else {
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
- }
- // The Write callback should not have been called.
- EXPECT_FALSE(callback.have_result());
- }
- // Tests that the SSLClientSocket does not crash if data is received on the
- // transport socket after a failing write. This can occur if we have a Write
- // error in a SPDY socket.
- // Regression test for http://crbug.com/335557
- TEST_P(SSLClientSocketReadTest, Read_WithWriteError) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- // Note: |error_socket|'s ownership is handed to |transport|, but a pointer
- // is retained in order to configure additional errors.
- auto error_socket =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(error_socket));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- // Send a request so there is something to read from the socket.
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- static const int kRequestTextSize =
- static_cast<int>(std::size(request_text) - 1);
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(kRequestTextSize);
- memcpy(request_buffer->data(), request_text, kRequestTextSize);
- rv = callback.GetResult(sock->Write(request_buffer.get(), kRequestTextSize,
- callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(kRequestTextSize, rv);
- // Start a hanging read.
- TestCompletionCallback read_callback;
- raw_transport->BlockReadResult();
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- rv = Read(sock.get(), buf.get(), 4096, read_callback.callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- // Perform another write, but have it fail. Write a request larger than the
- // internal socket buffers so that the request hits the underlying transport
- // socket and detects the error.
- std::string long_request_text =
- "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
- long_request_text.append(20 * 1024, '*');
- long_request_text.append("\r\n\r\n");
- scoped_refptr<DrainableIOBuffer> long_request_buffer =
- base::MakeRefCounted<DrainableIOBuffer>(
- base::MakeRefCounted<StringIOBuffer>(long_request_text),
- long_request_text.size());
- raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
- // Write as much data as possible until hitting an error.
- do {
- rv = callback.GetResult(sock->Write(
- long_request_buffer.get(), long_request_buffer->BytesRemaining(),
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- if (rv > 0) {
- long_request_buffer->DidConsume(rv);
- // Abort if the entire input is ever consumed. The input is larger than
- // the SSLClientSocket's write buffers.
- ASSERT_LT(0, long_request_buffer->BytesRemaining());
- }
- } while (rv > 0);
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
- // At this point the Read result is available. Transport write errors are
- // surfaced through Writes. See https://crbug.com/249848.
- rv = WaitForReadCompletion(sock.get(), buf.get(), 4096, &read_callback, rv);
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
- // Release the read. This does not cause a crash.
- raw_transport->UnblockReadResult();
- base::RunLoop().RunUntilIdle();
- }
- // Tests that SSLClientSocket fails the handshake if the underlying
- // transport is cleanly closed.
- TEST_F(SSLClientSocketTest, Connect_WithZeroReturn) {
- // There is no need to vary by TLS version because this test never reads a
- // response from the server.
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- SynchronousErrorStreamSocket* raw_transport = transport.get();
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- raw_transport->SetNextReadError(0);
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
- EXPECT_FALSE(sock->IsConnected());
- }
- // Tests that SSLClientSocket returns a Read of size 0 if the underlying socket
- // is cleanly closed, but the peer does not send close_notify.
- // This is a regression test for https://crbug.com/422246
- TEST_P(SSLClientSocketReadTest, Read_WithZeroReturn) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- SSLConfig config;
- config.disable_post_handshake_peek_for_testing = true;
- SynchronousErrorStreamSocket* raw_transport = transport.get();
- std::unique_ptr<SSLClientSocket> sock(
- CreateSSLClientSocket(std::move(transport), host_port_pair(), config));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- raw_transport->SetNextReadError(0);
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- rv = ReadAndWaitForCompletion(sock.get(), buf.get(), 4096);
- EXPECT_EQ(0, rv);
- }
- // Tests that SSLClientSocket cleanly returns a Read of size 0 if the
- // underlying socket is cleanly closed asynchronously.
- // This is a regression test for https://crbug.com/422246
- TEST_P(SSLClientSocketReadTest, Read_WithAsyncZeroReturn) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto error_socket =
- std::make_unique<SynchronousErrorStreamSocket>(std::move(real_transport));
- SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(error_socket));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- SSLConfig config;
- config.disable_post_handshake_peek_for_testing = true;
- std::unique_ptr<SSLClientSocket> sock(
- CreateSSLClientSocket(std::move(transport), host_port_pair(), config));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- raw_error_socket->SetNextReadError(0);
- raw_transport->BlockReadResult();
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- TestCompletionCallback read_callback;
- rv = Read(sock.get(), buf.get(), 4096, read_callback.callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->UnblockReadResult();
- rv = WaitForReadCompletion(sock.get(), buf.get(), 4096, &read_callback, rv);
- EXPECT_EQ(0, rv);
- }
- // Tests that fatal alerts from the peer are processed. This is a regression
- // test for https://crbug.com/466303.
- TEST_P(SSLClientSocketReadTest, Read_WithFatalAlert) {
- SSLServerConfig server_config = GetServerConfig();
- server_config.alert_after_handshake_for_testing = SSL_AD_INTERNAL_ERROR;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- // Receive the fatal alert.
- TestCompletionCallback callback;
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR,
- ReadAndWaitForCompletion(sock_.get(), buf.get(), 4096));
- }
- TEST_P(SSLClientSocketReadTest, Read_SmallChunks) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(std::size(request_text) - 1);
- memcpy(request_buffer->data(), request_text, std::size(request_text) - 1);
- TestCompletionCallback callback;
- rv = callback.GetResult(
- sock_->Write(request_buffer.get(), std::size(request_text) - 1,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(static_cast<int>(std::size(request_text) - 1), rv);
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(1);
- do {
- rv = ReadAndWaitForCompletion(sock_.get(), buf.get(), 1);
- EXPECT_GE(rv, 0);
- } while (rv > 0);
- }
- TEST_P(SSLClientSocketReadTest, Read_ManySmallRecords) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<ReadBufferingStreamSocket>(std::move(real_transport));
- ReadBufferingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- SSLConfig config;
- config.disable_post_handshake_peek_for_testing = true;
- std::unique_ptr<SSLClientSocket> sock(
- CreateSSLClientSocket(std::move(transport), host_port_pair(), config));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock->IsConnected());
- const char request_text[] = "GET /ssl-many-small-records HTTP/1.0\r\n\r\n";
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(std::size(request_text) - 1);
- memcpy(request_buffer->data(), request_text, std::size(request_text) - 1);
- rv = callback.GetResult(
- sock->Write(request_buffer.get(), std::size(request_text) - 1,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- ASSERT_GT(rv, 0);
- ASSERT_EQ(static_cast<int>(std::size(request_text) - 1), rv);
- // Note: This relies on SSLClientSocketNSS attempting to read up to 17K of
- // data (the max SSL record size) at a time. Ensure that at least 15K worth
- // of SSL data is buffered first. The 15K of buffered data is made up of
- // many smaller SSL records (the TestServer writes along 1350 byte
- // plaintext boundaries), although there may also be a few records that are
- // smaller or larger, due to timing and SSL False Start.
- // 15K was chosen because 15K is smaller than the 17K (max) read issued by
- // the SSLClientSocket implementation, and larger than the minimum amount
- // of ciphertext necessary to contain the 8K of plaintext requested below.
- raw_transport->BufferNextRead(15000);
- scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(8192);
- rv = ReadAndWaitForCompletion(sock.get(), buffer.get(), 8192);
- ASSERT_EQ(rv, 8192);
- }
- TEST_P(SSLClientSocketReadTest, Read_Interrupted) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(std::size(request_text) - 1);
- memcpy(request_buffer->data(), request_text, std::size(request_text) - 1);
- TestCompletionCallback callback;
- rv = callback.GetResult(
- sock_->Write(request_buffer.get(), std::size(request_text) - 1,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(static_cast<int>(std::size(request_text) - 1), rv);
- // Do a partial read and then exit. This test should not crash!
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(512);
- rv = ReadAndWaitForCompletion(sock_.get(), buf.get(), 512);
- EXPECT_GT(rv, 0);
- }
- TEST_P(SSLClientSocketReadTest, Read_FullLogging) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kEverything);
- auto transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, NetLog::Get(), NetLogSource());
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock->IsConnected());
- const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(std::size(request_text) - 1);
- memcpy(request_buffer->data(), request_text, std::size(request_text) - 1);
- rv = callback.GetResult(
- sock->Write(request_buffer.get(), std::size(request_text) - 1,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(static_cast<int>(std::size(request_text) - 1), rv);
- auto entries = log_observer_.GetEntries();
- size_t last_index = ExpectLogContainsSomewhereAfter(
- entries, 5, NetLogEventType::SSL_SOCKET_BYTES_SENT,
- NetLogEventPhase::NONE);
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- for (;;) {
- rv = ReadAndWaitForCompletion(sock.get(), buf.get(), 4096);
- EXPECT_GE(rv, 0);
- if (rv <= 0)
- break;
- entries = log_observer_.GetEntries();
- last_index = ExpectLogContainsSomewhereAfter(
- entries, last_index + 1, NetLogEventType::SSL_SOCKET_BYTES_RECEIVED,
- NetLogEventPhase::NONE);
- }
- }
- // Regression test for http://crbug.com/42538
- TEST_F(SSLClientSocketTest, PrematureApplicationData) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- static const unsigned char application_data[] = {
- 0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b,
- 0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46,
- 0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6,
- 0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36,
- 0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d,
- 0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f,
- 0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57,
- 0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82,
- 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
- 0x0a};
- // All reads and writes complete synchronously (async=false).
- MockRead data_reads[] = {
- MockRead(SYNCHRONOUS, reinterpret_cast<const char*>(application_data),
- std::size(application_data)),
- MockRead(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
- TestCompletionCallback callback;
- std::unique_ptr<StreamSocket> transport(
- std::make_unique<MockTCPClientSocket>(addr(), nullptr, &data));
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
- }
- TEST_F(SSLClientSocketTest, CipherSuiteDisables) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kModernTLS12Cipher;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLContextConfig ssl_context_config;
- ssl_context_config.disabled_cipher_suites.push_back(kModernTLS12Cipher);
- ssl_config_service_->UpdateSSLConfigAndNotify(ssl_context_config);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
- }
- // Test that connecting to a server only supporting TLS 1.0 will fail and
- // results in ERR_SSL_VERSION_OR_CIPHER_MISMATCH.
- TEST_F(SSLClientSocketTest, TLS1_NotSupported) {
- SSLServerConfig config;
- config.version_max = SSL_PROTOCOL_VERSION_TLS1;
- config.version_min = SSL_PROTOCOL_VERSION_TLS1;
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
- }
- // Test that connecting to a server only supporting TLS 1.1 will fail and
- // results in ERR_SSL_VERSION_OR_CIPHER_MISMATCH.
- TEST_F(SSLClientSocketTest, TLS1_1_NotSupported) {
- SSLServerConfig config;
- config.version_max = SSL_PROTOCOL_VERSION_TLS1_1;
- config.version_min = SSL_PROTOCOL_VERSION_TLS1_1;
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
- }
- // When creating an SSLClientSocket, it is allowed to pass in a
- // ClientSocketHandle that is not obtained from a client socket pool.
- // Here we verify that such a simple ClientSocketHandle, not associated with any
- // client socket pool, can be destroyed safely.
- TEST_F(SSLClientSocketTest, ClientSocketHandleNotFromPool) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- TestCompletionCallback callback;
- auto transport = std::make_unique<TCPClientSocket>(addr(), nullptr, nullptr,
- nullptr, NetLogSource());
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(socket_factory_->CreateSSLClientSocket(
- context_.get(), std::move(transport), host_port_pair(), SSLConfig()));
- EXPECT_FALSE(sock->IsConnected());
- rv = callback.GetResult(sock->Connect(callback.callback()));
- EXPECT_THAT(rv, IsOk());
- }
- // Verifies that SSLClientSocket::ExportKeyingMaterial return a success
- // code and different keying label results in different keying material.
- TEST_P(SSLClientSocketVersionTest, ExportKeyingMaterial) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- const int kKeyingMaterialSize = 32;
- const char kKeyingLabel1[] = "client-socket-test-1";
- const char kKeyingContext1[] = "";
- unsigned char client_out1[kKeyingMaterialSize];
- memset(client_out1, 0, sizeof(client_out1));
- rv = sock_->ExportKeyingMaterial(kKeyingLabel1, false, kKeyingContext1,
- client_out1, sizeof(client_out1));
- EXPECT_EQ(rv, OK);
- const char kKeyingLabel2[] = "client-socket-test-2";
- unsigned char client_out2[kKeyingMaterialSize];
- memset(client_out2, 0, sizeof(client_out2));
- rv = sock_->ExportKeyingMaterial(kKeyingLabel2, false, kKeyingContext1,
- client_out2, sizeof(client_out2));
- EXPECT_EQ(rv, OK);
- EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
- const char kKeyingContext2[] = "context";
- rv = sock_->ExportKeyingMaterial(kKeyingLabel1, true, kKeyingContext2,
- client_out2, sizeof(client_out2));
- EXPECT_EQ(rv, OK);
- EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
- // Prior to TLS 1.3, using an empty context should give different key material
- // from not using a context at all. In TLS 1.3, the distinction is deprecated
- // and they are the same.
- memset(client_out2, 0, sizeof(client_out2));
- rv = sock_->ExportKeyingMaterial(kKeyingLabel1, true, kKeyingContext1,
- client_out2, sizeof(client_out2));
- EXPECT_EQ(rv, OK);
- if (version() >= SSL_PROTOCOL_VERSION_TLS1_3) {
- EXPECT_EQ(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
- } else {
- EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
- }
- }
- TEST(SSLClientSocket, SerializeNextProtos) {
- NextProtoVector next_protos;
- next_protos.push_back(kProtoHTTP11);
- next_protos.push_back(kProtoHTTP2);
- static std::vector<uint8_t> serialized =
- SSLClientSocket::SerializeNextProtos(next_protos);
- ASSERT_EQ(12u, serialized.size());
- EXPECT_EQ(8, serialized[0]); // length("http/1.1")
- EXPECT_EQ('h', serialized[1]);
- EXPECT_EQ('t', serialized[2]);
- EXPECT_EQ('t', serialized[3]);
- EXPECT_EQ('p', serialized[4]);
- EXPECT_EQ('/', serialized[5]);
- EXPECT_EQ('1', serialized[6]);
- EXPECT_EQ('.', serialized[7]);
- EXPECT_EQ('1', serialized[8]);
- EXPECT_EQ(2, serialized[9]); // length("h2")
- EXPECT_EQ('h', serialized[10]);
- EXPECT_EQ('2', serialized[11]);
- }
- // Test that the server certificates are properly retrieved from the underlying
- // SSL stack.
- TEST_P(SSLClientSocketVersionTest, VerifyServerChainProperlyOrdered) {
- // The connection does not have to be successful.
- cert_verifier_->set_default_result(ERR_CERT_INVALID);
- // Set up a test server with CERT_CHAIN_WRONG_ROOT.
- // This makes the server present redundant-server-chain.pem, which contains
- // intermediate certificates.
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_CHAIN_WRONG_ROOT,
- GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_CERT_INVALID));
- EXPECT_FALSE(sock_->IsConnected());
- // When given option CERT_CHAIN_WRONG_ROOT, EmbeddedTestServer will present
- // certs from redundant-server-chain.pem.
- CertificateList server_certs =
- CreateCertificateListFromFile(GetTestCertsDirectory(),
- "redundant-server-chain.pem",
- X509Certificate::FORMAT_AUTO);
- // Get the server certificate as received client side.
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- scoped_refptr<X509Certificate> server_certificate = ssl_info.unverified_cert;
- // Get the intermediates as received client side.
- const auto& server_intermediates = server_certificate->intermediate_buffers();
- // Check that the unverified server certificate chain is properly retrieved
- // from the underlying ssl stack.
- ASSERT_EQ(4U, server_certs.size());
- EXPECT_TRUE(x509_util::CryptoBufferEqual(server_certificate->cert_buffer(),
- server_certs[0]->cert_buffer()));
- ASSERT_EQ(3U, server_intermediates.size());
- EXPECT_TRUE(x509_util::CryptoBufferEqual(server_intermediates[0].get(),
- server_certs[1]->cert_buffer()));
- EXPECT_TRUE(x509_util::CryptoBufferEqual(server_intermediates[1].get(),
- server_certs[2]->cert_buffer()));
- EXPECT_TRUE(x509_util::CryptoBufferEqual(server_intermediates[2].get(),
- server_certs[3]->cert_buffer()));
- sock_->Disconnect();
- EXPECT_FALSE(sock_->IsConnected());
- }
- // This tests that SSLInfo contains a properly re-constructed certificate
- // chain. That, in turn, verifies that GetSSLInfo is giving us the chain as
- // verified, not the chain as served by the server. (They may be different.)
- //
- // CERT_CHAIN_WRONG_ROOT is redundant-server-chain.pem. It contains A
- // (end-entity) -> B -> C, and C is signed by D. redundant-validated-chain.pem
- // contains a chain of A -> B -> C2, where C2 is the same public key as C, but
- // a self-signed root. Such a situation can occur when a new root (C2) is
- // cross-certified by an old root (D) and has two different versions of its
- // floating around. Servers may supply C2 as an intermediate, but the
- // SSLClientSocket should return the chain that was verified, from
- // verify_result, instead.
- TEST_P(SSLClientSocketVersionTest, VerifyReturnChainProperlyOrdered) {
- // By default, cause the CertVerifier to treat all certificates as
- // expired.
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- CertificateList unverified_certs = CreateCertificateListFromFile(
- GetTestCertsDirectory(), "redundant-server-chain.pem",
- X509Certificate::FORMAT_AUTO);
- ASSERT_EQ(4u, unverified_certs.size());
- // We will expect SSLInfo to ultimately contain this chain.
- CertificateList certs =
- CreateCertificateListFromFile(GetTestCertsDirectory(),
- "redundant-validated-chain.pem",
- X509Certificate::FORMAT_AUTO);
- ASSERT_EQ(3U, certs.size());
- ASSERT_TRUE(certs[0]->EqualsExcludingChain(unverified_certs[0].get()));
- std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> temp_intermediates;
- temp_intermediates.push_back(bssl::UpRef(certs[1]->cert_buffer()));
- temp_intermediates.push_back(bssl::UpRef(certs[2]->cert_buffer()));
- CertVerifyResult verify_result;
- verify_result.verified_cert = X509Certificate::CreateFromBuffer(
- bssl::UpRef(certs[0]->cert_buffer()), std::move(temp_intermediates));
- ASSERT_TRUE(verify_result.verified_cert);
- // Add a rule that maps the server cert (A) to the chain of A->B->C2
- // rather than A->B->C.
- cert_verifier_->AddResultForCert(certs[0].get(), verify_result, OK);
- // Load and install the root for the validated chain.
- scoped_refptr<X509Certificate> root_cert = ImportCertFromFile(
- GetTestCertsDirectory(), "redundant-validated-chain-root.pem");
- ASSERT_NE(static_cast<X509Certificate*>(nullptr), root_cert.get());
- ScopedTestRoot scoped_root(root_cert.get());
- // Set up a test server with CERT_CHAIN_WRONG_ROOT.
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_CHAIN_WRONG_ROOT,
- GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- auto entries = log_observer_.GetEntries();
- EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- // Verify that SSLInfo contains the corrected re-constructed chain A -> B
- // -> C2.
- ASSERT_TRUE(ssl_info.cert);
- const auto& intermediates = ssl_info.cert->intermediate_buffers();
- ASSERT_EQ(2U, intermediates.size());
- EXPECT_TRUE(x509_util::CryptoBufferEqual(ssl_info.cert->cert_buffer(),
- certs[0]->cert_buffer()));
- EXPECT_TRUE(x509_util::CryptoBufferEqual(intermediates[0].get(),
- certs[1]->cert_buffer()));
- EXPECT_TRUE(x509_util::CryptoBufferEqual(intermediates[1].get(),
- certs[2]->cert_buffer()));
- // Verify that SSLInfo also contains the chain as received from the server.
- ASSERT_TRUE(ssl_info.unverified_cert);
- const auto& served_intermediates =
- ssl_info.unverified_cert->intermediate_buffers();
- ASSERT_EQ(3U, served_intermediates.size());
- EXPECT_TRUE(x509_util::CryptoBufferEqual(ssl_info.cert->cert_buffer(),
- unverified_certs[0]->cert_buffer()));
- EXPECT_TRUE(x509_util::CryptoBufferEqual(served_intermediates[0].get(),
- unverified_certs[1]->cert_buffer()));
- EXPECT_TRUE(x509_util::CryptoBufferEqual(served_intermediates[1].get(),
- unverified_certs[2]->cert_buffer()));
- EXPECT_TRUE(x509_util::CryptoBufferEqual(served_intermediates[2].get(),
- unverified_certs[3]->cert_buffer()));
- sock_->Disconnect();
- EXPECT_FALSE(sock_->IsConnected());
- }
- INSTANTIATE_TEST_SUITE_P(TLSVersion,
- SSLClientSocketCertRequestInfoTest,
- ValuesIn(GetTLSVersions()));
- TEST_P(SSLClientSocketCertRequestInfoTest,
- DontRequestClientCertsIfServerCertInvalid) {
- SSLServerConfig config = GetServerConfig();
- config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_EXPIRED, config));
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_CERT_DATE_INVALID));
- }
- TEST_P(SSLClientSocketCertRequestInfoTest, NoAuthorities) {
- SSLServerConfig config = GetServerConfig();
- config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, config));
- scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest();
- ASSERT_TRUE(request_info.get());
- EXPECT_EQ(0u, request_info->cert_authorities.size());
- }
- TEST_P(SSLClientSocketCertRequestInfoTest, TwoAuthorities) {
- const unsigned char kThawteDN[] = {
- 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x5a, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x1c, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e,
- 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79,
- 0x29, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
- 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
- 0x53, 0x47, 0x43, 0x20, 0x43, 0x41};
- const unsigned char kDiginotarDN[] = {
- 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x4e, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
- 0x13, 0x09, 0x44, 0x69, 0x67, 0x69, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x31,
- 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x44, 0x69,
- 0x67, 0x69, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x20, 0x52, 0x6f, 0x6f, 0x74,
- 0x20, 0x43, 0x41, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48,
- 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x69, 0x6e, 0x66, 0x6f,
- 0x40, 0x64, 0x69, 0x67, 0x69, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x2e, 0x6e,
- 0x6c};
- SSLServerConfig config = GetServerConfig();
- config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- config.cert_authorities.emplace_back(std::begin(kThawteDN),
- std::end(kThawteDN));
- config.cert_authorities.emplace_back(std::begin(kDiginotarDN),
- std::end(kDiginotarDN));
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, config));
- scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest();
- ASSERT_TRUE(request_info.get());
- EXPECT_EQ(config.cert_authorities, request_info->cert_authorities);
- }
- TEST_P(SSLClientSocketCertRequestInfoTest, CertKeyTypes) {
- SSLServerConfig config = GetServerConfig();
- config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, config));
- scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest();
- ASSERT_TRUE(request_info.get());
- if (version() >= SSL_PROTOCOL_VERSION_TLS1_3) {
- // TLS 1.3 does not use cert_key_types, only signature algorithms. This
- // should be migrated to a more modern mechanism. See
- // https://crbug.com/1270530.
- EXPECT_EQ(0u, request_info->cert_key_types.size());
- } else {
- // BoringSSL always sends rsa_sign and ecdsa_sign.
- ASSERT_EQ(2u, request_info->cert_key_types.size());
- EXPECT_EQ(CLIENT_CERT_RSA_SIGN, request_info->cert_key_types[0]);
- EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, request_info->cert_key_types[1]);
- }
- }
- // Tests that the Certificate Transparency (RFC 6962) TLS extension is
- // supported.
- TEST_P(SSLClientSocketVersionTest, ConnectSignedCertTimestampsTLSExtension) {
- // Encoding of SCT List containing 'test'.
- base::StringPiece sct_ext("\x00\x06\x00\x04test", 8);
- SSLServerConfig server_config = GetServerConfig();
- server_config.signed_cert_timestamp_list =
- std::vector<uint8_t>(sct_ext.begin(), sct_ext.end());
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- auto ct_verifier = std::make_unique<MockCTVerifier>();
- // Check that the SCT list is extracted from the TLS extension as expected,
- // while also simulating that it was an unparsable response.
- SignedCertificateTimestampAndStatusList sct_list;
- EXPECT_CALL(*ct_verifier, Verify(_, _, _, sct_ext, _, _))
- .WillOnce(testing::SetArgPointee<4>(sct_list));
- auto cert_and_ct_verifier = std::make_unique<CertAndCTVerifier>(
- std::move(cert_verifier_), std::move(ct_verifier));
- context_ = std::make_unique<SSLClientContext>(
- ssl_config_service_.get(), cert_and_ct_verifier.get(),
- transport_security_state_.get(), ct_policy_enforcer_.get(),
- ssl_client_session_cache_.get(), nullptr);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->signed_cert_timestamps_received_);
- sock_ = nullptr;
- context_ = nullptr;
- }
- // Test that when a CT verifier and a CTPolicyEnforcer are defined, and
- // the EV certificate used conforms to the CT/EV policy, its EV status
- // is maintained.
- TEST_P(SSLClientSocketVersionTest, EVCertStatusMaintainedForCompliantCert) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- SSLConfig ssl_config;
- AddServerCertStatusToSSLConfig(CERT_STATUS_IS_EV, &ssl_config);
- // Emulate compliance of the certificate to the policy.
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(_, _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- EXPECT_THAT(rv, IsOk());
- SSLInfo result;
- ASSERT_TRUE(sock_->GetSSLInfo(&result));
- EXPECT_TRUE(result.cert_status & CERT_STATUS_IS_EV);
- }
- // Test that when a CT verifier and a CTPolicyEnforcer are defined, but
- // the EV certificate used does not conform to the CT/EV policy, its EV status
- // is removed.
- TEST_P(SSLClientSocketVersionTest, EVCertStatusRemovedForNonCompliantCert) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- SSLConfig ssl_config;
- AddServerCertStatusToSSLConfig(CERT_STATUS_IS_EV, &ssl_config);
- // Emulate non-compliance of the certificate to the policy.
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(_, _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- EXPECT_THAT(rv, IsOk());
- SSLInfo result;
- ASSERT_TRUE(sock_->GetSSLInfo(&result));
- EXPECT_FALSE(result.cert_status & CERT_STATUS_IS_EV);
- EXPECT_TRUE(result.cert_status & CERT_STATUS_CT_COMPLIANCE_FAILED);
- }
- // Tests that OCSP stapling is requested, as per Certificate Transparency (RFC
- // 6962).
- TEST_P(SSLClientSocketVersionTest, ConnectSignedCertTimestampsEnablesOCSP) {
- // The test server currently only knows how to generate OCSP responses
- // for a freshly minted certificate.
- EmbeddedTestServer::ServerCertificateConfig cert_config;
- cert_config.stapled_ocsp_config = EmbeddedTestServer::OCSPConfig(
- {{OCSPRevocationStatus::GOOD,
- EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}});
- ASSERT_TRUE(StartEmbeddedTestServer(cert_config, GetServerConfig()));
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->stapled_ocsp_response_received_);
- }
- // Tests that IsConnectedAndIdle and WasEverUsed behave as expected.
- TEST_P(SSLClientSocketVersionTest, ReuseStates) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- // The socket was just connected. It should be idle because it is speaking
- // HTTP. Although the transport has been used for the handshake, WasEverUsed()
- // returns false.
- EXPECT_TRUE(sock_->IsConnected());
- EXPECT_TRUE(sock_->IsConnectedAndIdle());
- EXPECT_FALSE(sock_->WasEverUsed());
- const char kRequestText[] = "GET / HTTP/1.0\r\n\r\n";
- const size_t kRequestLen = std::size(kRequestText) - 1;
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(kRequestLen);
- memcpy(request_buffer->data(), kRequestText, kRequestLen);
- TestCompletionCallback callback;
- rv = callback.GetResult(sock_->Write(request_buffer.get(), kRequestLen,
- callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_EQ(static_cast<int>(kRequestLen), rv);
- // The socket has now been used.
- EXPECT_TRUE(sock_->WasEverUsed());
- // TODO(davidben): Read one byte to ensure the test server has responded and
- // then assert IsConnectedAndIdle is false. This currently doesn't work
- // because SSLClientSocketImpl doesn't check the implementation's internal
- // buffer. Call SSL_pending.
- }
- // Tests that |is_fatal_cert_error| does not get set for a certificate error,
- // on a non-HSTS host.
- TEST_P(SSLClientSocketVersionTest, IsFatalErrorNotSetOnNonFatalError) {
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_CHAIN_WRONG_ROOT,
- GetServerConfig()));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_FALSE(ssl_info.is_fatal_cert_error);
- }
- // Tests that |is_fatal_cert_error| gets set for a certificate error on an
- // HSTS host.
- TEST_P(SSLClientSocketVersionTest, IsFatalErrorSetOnFatalError) {
- cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
- ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_CHAIN_WRONG_ROOT,
- GetServerConfig()));
- int rv;
- const base::Time expiry = base::Time::Now() + base::Seconds(1000);
- transport_security_state_->AddHSTS(host_port_pair().host(), expiry, true);
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_TRUE(ssl_info.is_fatal_cert_error);
- }
- // Tests that IsConnectedAndIdle treats a socket as idle even if a Write hasn't
- // been flushed completely out of SSLClientSocket's internal buffers. This is a
- // regression test for https://crbug.com/466147.
- TEST_P(SSLClientSocketVersionTest, ReusableAfterWrite) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- ASSERT_THAT(callback.GetResult(transport->Connect(callback.callback())),
- IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- ASSERT_THAT(callback.GetResult(sock->Connect(callback.callback())), IsOk());
- // Block any application data from reaching the network.
- raw_transport->BlockWrite();
- // Write a partial HTTP request.
- const char kRequestText[] = "GET / HTTP/1.0";
- const size_t kRequestLen = std::size(kRequestText) - 1;
- scoped_refptr<IOBuffer> request_buffer =
- base::MakeRefCounted<IOBuffer>(kRequestLen);
- memcpy(request_buffer->data(), kRequestText, kRequestLen);
- // Although transport writes are blocked, SSLClientSocketImpl completes the
- // outer Write operation.
- EXPECT_EQ(static_cast<int>(kRequestLen),
- callback.GetResult(sock->Write(request_buffer.get(), kRequestLen,
- callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS)));
- // The Write operation is complete, so the socket should be treated as
- // reusable, in case the server returns an HTTP response before completely
- // consuming the request body. In this case, we assume the server will
- // properly drain the request body before trying to read the next request.
- EXPECT_TRUE(sock->IsConnectedAndIdle());
- }
- // Tests that basic session resumption works.
- TEST_P(SSLClientSocketVersionTest, SessionResumption) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- // First, perform a full handshake.
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- // TLS 1.2 with False Start and TLS 1.3 cause the ticket to arrive later, so
- // use the socket to ensure the session ticket has been picked up.
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- // The next connection should resume.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- sock_.reset();
- // Using a different HostPortPair uses a different session cache key.
- auto transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, NetLog::Get(), NetLogSource());
- TestCompletionCallback callback;
- ASSERT_THAT(callback.GetResult(transport->Connect(callback.callback())),
- IsOk());
- std::unique_ptr<SSLClientSocket> sock = CreateSSLClientSocket(
- std::move(transport), HostPortPair("example.com", 443), ssl_config);
- ASSERT_THAT(callback.GetResult(sock->Connect(callback.callback())), IsOk());
- ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- sock.reset();
- ssl_client_session_cache_->Flush();
- // After clearing the session cache, the next handshake doesn't resume.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- }
- namespace {
- // FakePeerAddressSocket wraps a |StreamSocket|, forwarding all calls except
- // that it provides a given answer for |GetPeerAddress|.
- class FakePeerAddressSocket : public WrappedStreamSocket {
- public:
- FakePeerAddressSocket(std::unique_ptr<StreamSocket> socket,
- const IPEndPoint& address)
- : WrappedStreamSocket(std::move(socket)), address_(address) {}
- ~FakePeerAddressSocket() override = default;
- int GetPeerAddress(IPEndPoint* address) const override {
- *address = address_;
- return OK;
- }
- private:
- const IPEndPoint address_;
- };
- } // namespace
- TEST_F(SSLClientSocketTest, SessionResumption_RSA) {
- for (bool use_rsa : {false, true}) {
- SCOPED_TRACE(use_rsa);
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing =
- use_rsa ? kRSACipher : kModernTLS12Cipher;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig ssl_config;
- ssl_client_session_cache_->Flush();
- for (int i = 0; i < 3; i++) {
- SCOPED_TRACE(i);
- auto transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, NetLog::Get(), NetLogSource());
- TestCompletionCallback callback;
- ASSERT_THAT(callback.GetResult(transport->Connect(callback.callback())),
- IsOk());
- // The third handshake sees a different destination IP address.
- IPEndPoint fake_peer_address(IPAddress(1, 1, 1, i == 2 ? 2 : 1), 443);
- auto socket = std::make_unique<FakePeerAddressSocket>(
- std::move(transport), fake_peer_address);
- std::unique_ptr<SSLClientSocket> sock = CreateSSLClientSocket(
- std::move(socket), HostPortPair("example.com", 443), ssl_config);
- ASSERT_THAT(callback.GetResult(sock->Connect(callback.callback())),
- IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock->GetSSLInfo(&ssl_info));
- sock.reset();
- switch (i) {
- case 0:
- // Initial handshake should be a full handshake.
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- break;
- case 1:
- // Second handshake should resume.
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- break;
- case 2:
- // Third handshake gets a different IP address and, if the
- // session used RSA key exchange, it should not resume.
- EXPECT_EQ(
- use_rsa ? SSLInfo::HANDSHAKE_FULL : SSLInfo::HANDSHAKE_RESUME,
- ssl_info.handshake_type);
- break;
- default:
- NOTREACHED();
- }
- }
- }
- }
- // Tests that ALPN works with session resumption.
- TEST_F(SSLClientSocketTest, SessionResumptionAlpn) {
- SSLServerConfig server_config;
- server_config.alpn_protos = {NextProto::kProtoHTTP2, NextProto::kProtoHTTP11};
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // First, perform a full handshake.
- SSLConfig ssl_config;
- ssl_config.alpn_protos.push_back(kProtoHTTP2);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- EXPECT_EQ(kProtoHTTP2, sock_->GetNegotiatedProtocol());
- // TLS 1.2 with False Start and TLS 1.3 cause the ticket to arrive later, so
- // use the socket to ensure the session ticket has been picked up.
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- // The next connection should resume; ALPN should be renegotiated.
- ssl_config.alpn_protos.clear();
- ssl_config.alpn_protos.push_back(kProtoHTTP11);
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_EQ(kProtoHTTP11, sock_->GetNegotiatedProtocol());
- }
- // Tests that the session cache is not sharded by NetworkIsolationKey if the
- // feature is disabled.
- TEST_P(SSLClientSocketVersionTest,
- SessionResumptionNetworkIsolationKeyDisabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndDisableFeature(
- features::kPartitionSSLSessionsByNetworkIsolationKey);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- // First, perform a full handshake.
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- // TLS 1.2 with False Start and TLS 1.3 cause the ticket to arrive later, so
- // use the socket to ensure the session ticket has been picked up. Do this for
- // every connection to avoid problems with TLS 1.3 single-use tickets.
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- // The next connection should resume.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- // Using a different NetworkIsolationKey shares session cache key because
- // sharding is disabled.
- const SchemefulSite kSiteA(GURL("https://a.test"));
- ssl_config.network_isolation_key = NetworkIsolationKey(kSiteA, kSiteA);
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- const SchemefulSite kSiteB(GURL("https://a.test"));
- ssl_config.network_isolation_key = NetworkIsolationKey(kSiteB, kSiteB);
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- }
- // Tests that the session cache is sharded by NetworkIsolationKey if the
- // feature is enabled.
- TEST_P(SSLClientSocketVersionTest,
- SessionResumptionNetworkIsolationKeyEnabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- features::kPartitionSSLSessionsByNetworkIsolationKey);
- const SchemefulSite kSiteA(GURL("https://a.test"));
- const SchemefulSite kSiteB(GURL("https://b.test"));
- const NetworkIsolationKey kNetworkIsolationKeyA(kSiteA, kSiteA);
- const NetworkIsolationKey kNetworkIsolationKeyB(kSiteB, kSiteB);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- // First, perform a full handshake.
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- // TLS 1.2 with False Start and TLS 1.3 cause the ticket to arrive later, so
- // use the socket to ensure the session ticket has been picked up. Do this for
- // every connection to avoid problems with TLS 1.3 single-use tickets.
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- // The next connection should resume.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- // Using a different NetworkIsolationKey uses a different session cache key.
- ssl_config.network_isolation_key = kNetworkIsolationKeyA;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- // We, however, can resume under that newly-established session.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- // Repeat with another non-null key.
- ssl_config.network_isolation_key = kNetworkIsolationKeyB;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- // b.test does not evict a.test's session.
- ssl_config.network_isolation_key = kNetworkIsolationKeyA;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- sock_.reset();
- }
- // Tests that connections with certificate errors do not add entries to the
- // session cache.
- TEST_P(SSLClientSocketVersionTest, CertificateErrorNoResume) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- cert_verifier_->set_default_result(ERR_CERT_COMMON_NAME_INVALID);
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsError(ERR_CERT_COMMON_NAME_INVALID));
- cert_verifier_->set_default_result(OK);
- // The next connection should perform a full handshake.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_THAT(rv, IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- }
- TEST_F(SSLClientSocketTest, RequireECDHE) {
- // Run test server without ECDHE.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kRSACipher;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig config;
- config.require_ecdhe = true;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
- }
- TEST_F(SSLClientSocketTest, 3DES) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = k3DESCipher;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // 3DES is always disabled.
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
- }
- TEST_F(SSLClientSocketTest, SHA1) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- // Disable RSA key exchange, to ensure the server does not pick a non-signing
- // cipher.
- server_config.require_ecdhe = true;
- server_config.signature_algorithm_for_testing = SSL_SIGN_RSA_PKCS1_SHA1;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- SSLConfig config;
- config.disable_legacy_crypto = true;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
- }
- TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) {
- // False Start requires ALPN, ECDHE, and an AEAD.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kModernTLS12Cipher;
- server_config.alpn_protos = {NextProto::kProtoHTTP11};
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_config, client_config, true));
- }
- // Test that False Start is disabled without ALPN.
- TEST_F(SSLClientSocketFalseStartTest, NoAlpn) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kModernTLS12Cipher;
- SSLConfig client_config;
- client_config.alpn_protos.clear();
- ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_config, client_config, false));
- }
- // Test that False Start is disabled with plain RSA ciphers.
- TEST_F(SSLClientSocketFalseStartTest, RSA) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kRSACipher;
- server_config.alpn_protos = {NextProto::kProtoHTTP11};
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_config, client_config, false));
- }
- // Test that False Start is disabled without an AEAD.
- TEST_F(SSLClientSocketFalseStartTest, NoAEAD) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kCBCCipher;
- server_config.alpn_protos = {NextProto::kProtoHTTP11};
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_config, client_config, false));
- }
- // Test that sessions are resumable after receiving the server Finished message.
- TEST_F(SSLClientSocketFalseStartTest, SessionResumption) {
- // Start a server.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kModernTLS12Cipher;
- server_config.alpn_protos = {NextProto::kProtoHTTP11};
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- // Let a full handshake complete with False Start.
- ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_config, client_config, true));
- // Make a second connection.
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- // It should resume the session.
- SSLInfo ssl_info;
- EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- // Test that the client completes the handshake in the background and installs
- // new sessions, even if the socket isn't used. This also avoids a theoretical
- // deadlock if NewSessionTicket is sufficiently large that neither it nor the
- // client's HTTP/1.1 POST fit in transport windows.
- TEST_F(SSLClientSocketFalseStartTest, CompleteHandshakeWithoutRequest) {
- // Start a server.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kModernTLS12Cipher;
- server_config.alpn_protos = {NextProto::kProtoHTTP11};
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- // Start a handshake up to the server Finished message.
- TestCompletionCallback callback;
- FakeBlockingStreamSocket* raw_transport = nullptr;
- std::unique_ptr<SSLClientSocket> sock;
- ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
- client_config, &callback, &raw_transport, &sock));
- // Wait for the server Finished to arrive, release it, and allow
- // SSLClientSocket to process it. This should install a session. It make take
- // a few iterations to complete if the server writes in small chunks
- while (ssl_client_session_cache_->size() == 0) {
- raw_transport->WaitForReadResult();
- raw_transport->UnblockReadResult();
- base::RunLoop().RunUntilIdle();
- raw_transport->BlockReadResult();
- }
- // Drop the old socket. This is needed because the Python test server can't
- // service two sockets in parallel.
- sock.reset();
- // Make a second connection.
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- // It should resume the session.
- SSLInfo ssl_info;
- EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- // Test that False Started sessions are not resumable before receiving the
- // server Finished message.
- TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinished) {
- // Start a server.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kModernTLS12Cipher;
- server_config.alpn_protos = {NextProto::kProtoHTTP11};
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- // Start a handshake up to the server Finished message.
- TestCompletionCallback callback;
- FakeBlockingStreamSocket* raw_transport1 = nullptr;
- std::unique_ptr<SSLClientSocket> sock1;
- ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
- client_config, &callback, &raw_transport1, &sock1));
- // Although raw_transport1 has the server Finished blocked, the handshake
- // still completes.
- EXPECT_THAT(callback.WaitForResult(), IsOk());
- // Continue to block the client (|sock1|) from processing the Finished
- // message, but allow it to arrive on the socket. This ensures that, from the
- // server's point of view, it has completed the handshake and added the
- // session to its session cache.
- //
- // The actual read on |sock1| will not complete until the Finished message is
- // processed; however, pump the underlying transport so that it is read from
- // the socket. NOTE: This may flakily pass if the server's final flight
- // doesn't come in one Read.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int rv = sock1->Read(buf.get(), 4096, callback.callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport1->WaitForReadResult();
- // Drop the old socket. This is needed because the Python test server can't
- // service two sockets in parallel.
- sock1.reset();
- // Start a second connection.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- // No session resumption because the first connection never received a server
- // Finished message.
- SSLInfo ssl_info;
- EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- }
- // Test that False Started sessions are not resumable if the server Finished
- // message was bad.
- TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBadFinished) {
- // Start a server.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = kModernTLS12Cipher;
- server_config.alpn_protos = {NextProto::kProtoHTTP11};
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- // Start a handshake up to the server Finished message.
- TestCompletionCallback callback;
- FakeBlockingStreamSocket* raw_transport1 = nullptr;
- std::unique_ptr<SSLClientSocket> sock1;
- ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived(
- client_config, &callback, &raw_transport1, &sock1));
- // Although raw_transport1 has the server Finished blocked, the handshake
- // still completes.
- EXPECT_THAT(callback.WaitForResult(), IsOk());
- // Continue to block the client (|sock1|) from processing the Finished
- // message, but allow it to arrive on the socket. This ensures that, from the
- // server's point of view, it has completed the handshake and added the
- // session to its session cache.
- //
- // The actual read on |sock1| will not complete until the Finished message is
- // processed; however, pump the underlying transport so that it is read from
- // the socket.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int rv = sock1->Read(buf.get(), 4096, callback.callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport1->WaitForReadResult();
- // The server's second leg, or part of it, is now received but not yet sent to
- // |sock1|. Before doing so, break the server's second leg.
- int bytes_read = raw_transport1->pending_read_result();
- ASSERT_LT(0, bytes_read);
- raw_transport1->pending_read_buf()->data()[bytes_read - 1]++;
- // Unblock the Finished message. |sock1->Read| should now fail.
- raw_transport1->UnblockReadResult();
- EXPECT_THAT(callback.GetResult(rv), IsError(ERR_SSL_PROTOCOL_ERROR));
- // Drop the old socket. This is needed because the Python test server can't
- // service two sockets in parallel.
- sock1.reset();
- // Start a second connection.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- // No session resumption because the first connection never received a server
- // Finished message.
- SSLInfo ssl_info;
- EXPECT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- }
- // Server preference should win in ALPN.
- TEST_F(SSLClientSocketTest, Alpn) {
- SSLServerConfig server_config;
- server_config.alpn_protos = {NextProto::kProtoHTTP2, NextProto::kProtoHTTP11};
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig client_config;
- client_config.alpn_protos.push_back(kProtoHTTP11);
- client_config.alpn_protos.push_back(kProtoHTTP2);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_EQ(kProtoHTTP2, sock_->GetNegotiatedProtocol());
- }
- // If the server supports ALPN but the client does not, then ALPN is not used.
- TEST_F(SSLClientSocketTest, AlpnClientDisabled) {
- SSLServerConfig server_config;
- server_config.alpn_protos = {NextProto::kProtoHTTP2};
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig client_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_EQ(kProtoUnknown, sock_->GetNegotiatedProtocol());
- }
- // Connect to a server requesting client authentication, do not send
- // any client certificates. It should refuse the connection.
- TEST_P(SSLClientSocketVersionTest, NoCert) {
- SSLServerConfig server_config = GetServerConfig();
- server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
- EXPECT_FALSE(sock_->IsConnected());
- }
- // Connect to a server requesting client authentication, and send it
- // an empty certificate.
- TEST_P(SSLClientSocketVersionTest, SendEmptyCert) {
- SSLServerConfig server_config = GetServerConfig();
- server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- context_->SetClientCertificate(host_port_pair(), nullptr, nullptr);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_FALSE(ssl_info.client_cert_sent);
- }
- // Connect to a server requesting client authentication and send a certificate.
- TEST_P(SSLClientSocketVersionTest, SendGoodCert) {
- base::FilePath certs_dir = GetTestCertsDirectory();
- scoped_refptr<X509Certificate> client_cert =
- ImportCertFromFile(certs_dir, "client_1.pem");
- ASSERT_TRUE(client_cert);
- // Configure the server to only accept |client_cert|.
- MockClientCertVerifier verifier;
- verifier.set_default_result(ERR_CERT_INVALID);
- verifier.AddResultForCert(client_cert.get(), OK);
- SSLServerConfig server_config = GetServerConfig();
- server_config.client_cert_type = SSLServerConfig::REQUIRE_CLIENT_CERT;
- server_config.client_cert_verifier = &verifier;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- context_->SetClientCertificate(
- host_port_pair(), client_cert,
- key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_TRUE(ssl_info.client_cert_sent);
- sock_->Disconnect();
- EXPECT_FALSE(sock_->IsConnected());
- // Shut down the test server before |verifier| goes out of scope.
- ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
- }
- // When client certificate preferences change, the session cache should be
- // cleared so the client certificate preferences are applied.
- TEST_F(SSLClientSocketTest, ClearSessionCacheOnClientCertChange) {
- SSLServerConfig server_config;
- // TLS 1.3 reports client certificate errors after the handshake, so test at
- // TLS 1.2 for simplicity.
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.client_cert_type = SSLServerConfig::REQUIRE_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // Connecting without a client certificate will fail with
- // ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
- // Configure a client certificate.
- base::FilePath certs_dir = GetTestCertsDirectory();
- context_->SetClientCertificate(
- host_port_pair(), ImportCertFromFile(certs_dir, "client_1.pem"),
- key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")));
- // Now the connection succeeds.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_TRUE(ssl_info.client_cert_sent);
- EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_FULL);
- // Make a second connection. This should resume the session from the previous
- // connection.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_TRUE(ssl_info.client_cert_sent);
- EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_RESUME);
- // Clear the client certificate preference.
- context_->ClearClientCertificate(host_port_pair());
- // Connections return to failing, rather than resume the previous session.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
- // Establish a new session with the correct client certificate.
- context_->SetClientCertificate(
- host_port_pair(), ImportCertFromFile(certs_dir, "client_1.pem"),
- key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")));
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_TRUE(ssl_info.client_cert_sent);
- EXPECT_EQ(ssl_info.handshake_type, SSLInfo::HANDSHAKE_FULL);
- // Switch to continuing without a client certificate.
- context_->SetClientCertificate(host_port_pair(), nullptr, nullptr);
- // This also clears the session cache and the new preference is applied.
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
- }
- HashValueVector MakeHashValueVector(uint8_t value) {
- HashValueVector out;
- HashValue hash(HASH_VALUE_SHA256);
- memset(hash.data(), value, hash.size());
- out.push_back(hash);
- return out;
- }
- // Test that |ssl_info.pkp_bypassed| is set when a local trust anchor causes
- // pinning to be bypassed.
- TEST_P(SSLClientSocketVersionTest, PKPBypassedSet) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(
- net::features::kStaticKeyPinningEnforcement);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // The certificate needs to be trusted, but chain to a local root with
- // different public key hashes than specified in the pin.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = false;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kBadHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- transport_security_state_->EnableStaticPinsForTesting();
- transport_security_state_->SetPinningListAlwaysTimelyForTesting(true);
- ScopedTransportSecurityStateSource scoped_security_state_source;
- SSLConfig ssl_config;
- int rv;
- HostPortPair new_host_port_pair("example.test", host_port_pair().port());
- ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(ssl_config,
- new_host_port_pair, &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- EXPECT_TRUE(ssl_info.pkp_bypassed);
- EXPECT_FALSE(ssl_info.cert_status & CERT_STATUS_PINNED_KEY_MISSING);
- }
- TEST_P(SSLClientSocketVersionTest, PKPEnforced) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(
- net::features::kStaticKeyPinningEnforcement);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // Certificate is trusted, but chains to a public root that doesn't match the
- // pin hashes.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = true;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kBadHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- transport_security_state_->EnableStaticPinsForTesting();
- transport_security_state_->SetPinningListAlwaysTimelyForTesting(true);
- ScopedTransportSecurityStateSource scoped_security_state_source;
- SSLConfig ssl_config;
- int rv;
- HostPortPair new_host_port_pair("example.test", host_port_pair().port());
- ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(ssl_config,
- new_host_port_pair, &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_THAT(rv, IsError(ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN));
- EXPECT_TRUE(ssl_info.cert_status & CERT_STATUS_PINNED_KEY_MISSING);
- EXPECT_FALSE(sock_->IsConnected());
- EXPECT_FALSE(ssl_info.pkp_bypassed);
- }
- namespace {
- // TLS_RSA_WITH_AES_128_GCM_SHA256's key exchange involves encrypting to the
- // server long-term key.
- const uint16_t kEncryptingCipher = kRSACipher;
- // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256's key exchange involves a signature by
- // the server long-term key.
- const uint16_t kSigningCipher = kModernTLS12Cipher;
- } // namespace
- struct KeyUsageTest {
- EmbeddedTestServer::ServerCertificate server_cert;
- uint16_t cipher_suite;
- bool known_root;
- bool success;
- };
- class SSLClientSocketKeyUsageTest
- : public SSLClientSocketTest,
- public ::testing::WithParamInterface<struct KeyUsageTest> {};
- const struct KeyUsageTest kKeyUsageTests[] = {
- // Known Root: Success iff keyUsage allows the key exchange method
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_ENCIPHERMENT, kSigningCipher, true,
- false},
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_DIGITAL_SIGNATURE, kSigningCipher,
- true, true},
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_ENCIPHERMENT, kEncryptingCipher,
- true, true},
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_DIGITAL_SIGNATURE,
- kEncryptingCipher, true, false},
- // Unknown Root: Always succeeds
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_ENCIPHERMENT, kSigningCipher, false,
- true},
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_DIGITAL_SIGNATURE, kSigningCipher,
- false, true},
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_ENCIPHERMENT, kEncryptingCipher,
- false, true},
- {EmbeddedTestServer::CERT_KEY_USAGE_RSA_DIGITAL_SIGNATURE,
- kEncryptingCipher, false, true},
- };
- TEST_P(SSLClientSocketKeyUsageTest, RSAKeyUsageEnforcedForKnownRoot) {
- const KeyUsageTest test = GetParam();
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.cipher_suite_for_testing = test.cipher_suite;
- ASSERT_TRUE(StartEmbeddedTestServer(test.server_cert, server_config));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // Certificate is trusted.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = test.known_root;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kGoodHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- if (test.success) {
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(sock_->IsConnected());
- } else {
- EXPECT_THAT(rv, IsError(ERR_SSL_KEY_USAGE_INCOMPATIBLE));
- EXPECT_FALSE(sock_->IsConnected());
- }
- }
- INSTANTIATE_TEST_SUITE_P(RSAKeyUsageInstantiation,
- SSLClientSocketKeyUsageTest,
- ValuesIn(kKeyUsageTests));
- // Test that when CT is required (in this case, by the delegate), the
- // absence of CT information is a socket error.
- TEST_P(SSLClientSocketVersionTest, CTIsRequired) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // Certificate is trusted and chains to a public root.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = true;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kGoodHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- // Set up CT
- MockRequireCTDelegate require_ct_delegate;
- transport_security_state_->SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
- .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
- CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate,
- IsCTRequiredForHost(host_port_pair().host(), _, _))
- .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
- CTRequirementLevel::REQUIRED));
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_THAT(rv, IsError(ERR_CERTIFICATE_TRANSPARENCY_REQUIRED));
- EXPECT_TRUE(ssl_info.cert_status &
- CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
- EXPECT_FALSE(sock_->IsConnected());
- }
- // Test that when CT is required, setting ignore_certificate_errors
- // ignores errors in CT.
- TEST_P(SSLClientSocketVersionTest, IgnoreCertificateErrorsBypassesRequiredCT) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // Certificate is trusted and chains to a public root.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = true;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kGoodHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- // Set up CT
- MockRequireCTDelegate require_ct_delegate;
- transport_security_state_->SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
- .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
- CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate,
- IsCTRequiredForHost(host_port_pair().host(), _, _))
- .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
- CTRequirementLevel::REQUIRED));
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- SSLConfig ssl_config;
- ssl_config.ignore_certificate_errors = true;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(ssl_info.cert_status &
- CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
- EXPECT_TRUE(sock_->IsConnected());
- }
- // Test that when CT is required (in this case, by an Expect-CT opt-in), the
- // absence of CT information is a socket error.
- TEST_P(SSLClientSocketVersionTest, CTIsRequiredByExpectCT) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- TransportSecurityState::kDynamicExpectCTFeature);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // Certificate is trusted and chains to a public root.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = true;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kGoodHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- // Set up the Expect-CT opt-in.
- NetworkIsolationKey network_isolation_key =
- NetworkIsolationKey::CreateTransient();
- const base::Time current_time(base::Time::Now());
- const base::Time expiry = current_time + base::Seconds(1000);
- transport_security_state_->AddExpectCT(
- host_port_pair().host(), expiry, true /* enforce */,
- GURL("https://example-report.test"), network_isolation_key);
- MockExpectCTReporter reporter;
- transport_security_state_->SetExpectCTReporter(&reporter);
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- SSLConfig ssl_config;
- ssl_config.network_isolation_key = network_isolation_key;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_THAT(rv, IsError(ERR_CERTIFICATE_TRANSPARENCY_REQUIRED));
- EXPECT_TRUE(ssl_info.cert_status &
- CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
- EXPECT_FALSE(sock_->IsConnected());
- EXPECT_EQ(1u, reporter.num_failures());
- EXPECT_EQ(GURL("https://example-report.test"), reporter.report_uri());
- EXPECT_EQ(ssl_info.unverified_cert.get(),
- reporter.served_certificate_chain());
- EXPECT_EQ(ssl_info.cert.get(), reporter.validated_certificate_chain());
- EXPECT_EQ(0u, reporter.signed_certificate_timestamps().size());
- EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
- transport_security_state_->ClearReportCachesForTesting();
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_THAT(rv, IsError(ERR_CERTIFICATE_TRANSPARENCY_REQUIRED));
- EXPECT_TRUE(ssl_info.cert_status &
- CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
- EXPECT_FALSE(sock_->IsConnected());
- EXPECT_EQ(2u, reporter.num_failures());
- EXPECT_EQ(GURL("https://example-report.test"), reporter.report_uri());
- EXPECT_EQ(ssl_info.unverified_cert.get(),
- reporter.served_certificate_chain());
- EXPECT_EQ(ssl_info.cert.get(), reporter.validated_certificate_chain());
- EXPECT_EQ(0u, reporter.signed_certificate_timestamps().size());
- EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
- // If the connection is CT compliant, then there should be no socket error nor
- // a report.
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(net::OK, rv);
- EXPECT_FALSE(ssl_info.cert_status &
- CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
- EXPECT_TRUE(sock_->IsConnected());
- EXPECT_EQ(2u, reporter.num_failures());
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(net::OK, rv);
- EXPECT_FALSE(ssl_info.cert_status &
- CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
- EXPECT_TRUE(sock_->IsConnected());
- EXPECT_EQ(2u, reporter.num_failures());
- }
- // When both PKP and CT are required for a host, and both fail, the more
- // serious error is that the pin validation failed.
- TEST_P(SSLClientSocketVersionTest, PKPMoreImportantThanCT) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(
- net::features::kStaticKeyPinningEnforcement);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // Certificate is trusted, but chains to a public root that doesn't match the
- // pin hashes.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = true;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kBadHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- transport_security_state_->EnableStaticPinsForTesting();
- transport_security_state_->SetPinningListAlwaysTimelyForTesting(true);
- ScopedTransportSecurityStateSource scoped_security_state_source;
- const char kCTHost[] = "pkp-expect-ct.preloaded.test";
- // Set up CT.
- MockRequireCTDelegate require_ct_delegate;
- transport_security_state_->SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
- .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
- CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kCTHost, _, _))
- .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
- CTRequirementLevel::REQUIRED));
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- SSLConfig ssl_config;
- int rv;
- HostPortPair ct_host_port_pair(kCTHost, host_port_pair().port());
- ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(ssl_config,
- ct_host_port_pair, &rv));
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_THAT(rv, IsError(ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN));
- EXPECT_TRUE(ssl_info.cert_status & CERT_STATUS_PINNED_KEY_MISSING);
- EXPECT_TRUE(ssl_info.cert_status &
- CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
- EXPECT_FALSE(sock_->IsConnected());
- }
- // Tests that the SCTAuditingDelegate is called to enqueue SCT reports.
- TEST_P(SSLClientSocketVersionTest, SCTAuditingReportCollected) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, GetServerConfig()));
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- // Certificate is trusted and chains to a public root.
- CertVerifyResult verify_result;
- verify_result.is_issued_by_known_root = true;
- verify_result.verified_cert = server_cert;
- verify_result.public_key_hashes =
- MakeHashValueVector(kGoodHashValueVectorInput);
- cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
- // Set up CT and auditing delegate.
- MockRequireCTDelegate require_ct_delegate;
- transport_security_state_->SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
- .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
- CTRequirementLevel::REQUIRED));
- EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
- .WillRepeatedly(
- Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- MockSCTAuditingDelegate sct_auditing_delegate;
- context_ = std::make_unique<SSLClientContext>(
- ssl_config_service_.get(), cert_verifier_.get(),
- transport_security_state_.get(), ct_policy_enforcer_.get(),
- ssl_client_session_cache_.get(), &sct_auditing_delegate);
- EXPECT_CALL(sct_auditing_delegate, IsSCTAuditingEnabled())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(sct_auditing_delegate,
- MaybeEnqueueReport(host_port_pair(), server_cert.get(), _))
- .Times(1);
- SSLConfig ssl_config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- EXPECT_THAT(rv, 0);
- EXPECT_TRUE(sock_->IsConnected());
- }
- // Test that handshake_failure alerts at the ServerHello are mapped to
- // ERR_SSL_VERSION_OR_CIPHER_MISMATCH.
- TEST_F(SSLClientSocketTest, HandshakeFailureServerHello) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- // Connect. Stop before the client processes ServerHello.
- raw_transport->BlockReadResult();
- rv = sock->Connect(callback.callback());
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->WaitForReadResult();
- // Replace it with an alert.
- raw_transport->ReplaceReadResult(
- FormatTLS12Alert(40 /* AlertDescription.handshake_failure */));
- raw_transport->UnblockReadResult();
- rv = callback.GetResult(rv);
- EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
- }
- // Test that handshake_failure alerts after the ServerHello but without a
- // CertificateRequest are mapped to ERR_SSL_PROTOCOL_ERROR.
- TEST_F(SSLClientSocketTest, HandshakeFailureNoClientCerts) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- // Connect. Stop before the client processes ServerHello.
- raw_transport->BlockReadResult();
- rv = sock->Connect(callback.callback());
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->WaitForReadResult();
- // Release the ServerHello and wait for the client to write its second flight.
- raw_transport->BlockWrite();
- raw_transport->UnblockReadResult();
- raw_transport->WaitForWrite();
- // Wait for the server's final flight.
- raw_transport->BlockReadResult();
- raw_transport->UnblockWrite();
- raw_transport->WaitForReadResult();
- // Replace it with an alert.
- raw_transport->ReplaceReadResult(
- FormatTLS12Alert(40 /* AlertDescription.handshake_failure */));
- raw_transport->UnblockReadResult();
- rv = callback.GetResult(rv);
- EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
- }
- // Test that handshake_failure alerts after the ServerHello map to
- // ERR_BAD_SSL_CLIENT_AUTH_CERT if a client certificate was requested but not
- // supplied. TLS does not have an alert for this case, so handshake_failure is
- // common. See https://crbug.com/646567.
- TEST_F(SSLClientSocketTest, LateHandshakeFailureMissingClientCerts) {
- // Request a client certificate.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- // Send no client certificate.
- context_->SetClientCertificate(host_port_pair(), nullptr, nullptr);
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- // Connect. Stop before the client processes ServerHello.
- raw_transport->BlockReadResult();
- rv = sock->Connect(callback.callback());
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->WaitForReadResult();
- // Release the ServerHello and wait for the client to write its second flight.
- raw_transport->BlockWrite();
- raw_transport->UnblockReadResult();
- raw_transport->WaitForWrite();
- // Wait for the server's final flight.
- raw_transport->BlockReadResult();
- raw_transport->UnblockWrite();
- raw_transport->WaitForReadResult();
- // Replace it with an alert.
- raw_transport->ReplaceReadResult(
- FormatTLS12Alert(40 /* AlertDescription.handshake_failure */));
- raw_transport->UnblockReadResult();
- rv = callback.GetResult(rv);
- EXPECT_THAT(rv, IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
- }
- // Test that handshake_failure alerts after the ServerHello map to
- // ERR_SSL_PROTOCOL_ERROR if received after sending a client certificate. It is
- // assumed servers will send a more appropriate alert in this case.
- TEST_F(SSLClientSocketTest, LateHandshakeFailureSendClientCerts) {
- // Request a client certificate.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- // Send a client certificate.
- base::FilePath certs_dir = GetTestCertsDirectory();
- context_->SetClientCertificate(
- host_port_pair(), ImportCertFromFile(certs_dir, "client_1.pem"),
- key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")));
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- // Connect. Stop before the client processes ServerHello.
- raw_transport->BlockReadResult();
- rv = sock->Connect(callback.callback());
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->WaitForReadResult();
- // Release the ServerHello and wait for the client to write its second flight.
- raw_transport->BlockWrite();
- raw_transport->UnblockReadResult();
- raw_transport->WaitForWrite();
- // Wait for the server's final flight.
- raw_transport->BlockReadResult();
- raw_transport->UnblockWrite();
- raw_transport->WaitForReadResult();
- // Replace it with an alert.
- raw_transport->ReplaceReadResult(
- FormatTLS12Alert(40 /* AlertDescription.handshake_failure */));
- raw_transport->UnblockReadResult();
- rv = callback.GetResult(rv);
- EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
- }
- // Test that access_denied alerts are mapped to ERR_SSL_PROTOCOL_ERROR if
- // received on a connection not requesting client certificates. This is an
- // incorrect use of the alert but is common. See https://crbug.com/630883.
- TEST_F(SSLClientSocketTest, AccessDeniedNoClientCerts) {
- // Request a client certificate.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- // Connect. Stop before the client processes ServerHello.
- raw_transport->BlockReadResult();
- rv = sock->Connect(callback.callback());
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->WaitForReadResult();
- // Release the ServerHello and wait for the client to write its second flight.
- raw_transport->BlockWrite();
- raw_transport->UnblockReadResult();
- raw_transport->WaitForWrite();
- // Wait for the server's final flight.
- raw_transport->BlockReadResult();
- raw_transport->UnblockWrite();
- raw_transport->WaitForReadResult();
- // Replace it with an alert.
- raw_transport->ReplaceReadResult(
- FormatTLS12Alert(49 /* AlertDescription.access_denied */));
- raw_transport->UnblockReadResult();
- rv = callback.GetResult(rv);
- EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
- }
- // Test that access_denied alerts are mapped to ERR_BAD_SSL_CLIENT_AUTH_CERT if
- // received on a connection requesting client certificates.
- TEST_F(SSLClientSocketTest, AccessDeniedClientCerts) {
- // Request a client certificate.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- TestCompletionCallback callback;
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- int rv = callback.GetResult(transport->Connect(callback.callback()));
- ASSERT_THAT(rv, IsOk());
- // Send a client certificate.
- base::FilePath certs_dir = GetTestCertsDirectory();
- context_->SetClientCertificate(
- host_port_pair(), ImportCertFromFile(certs_dir, "client_1.pem"),
- key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key")));
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(transport), host_port_pair(), SSLConfig()));
- // Connect. Stop before the client processes ServerHello.
- raw_transport->BlockReadResult();
- rv = sock->Connect(callback.callback());
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- raw_transport->WaitForReadResult();
- // Release the ServerHello and wait for the client to write its second flight.
- raw_transport->BlockWrite();
- raw_transport->UnblockReadResult();
- raw_transport->WaitForWrite();
- // Wait for the server's final flight.
- raw_transport->BlockReadResult();
- raw_transport->UnblockWrite();
- raw_transport->WaitForReadResult();
- // Replace it with an alert.
- raw_transport->ReplaceReadResult(
- FormatTLS12Alert(49 /* AlertDescription.access_denied */));
- raw_transport->UnblockReadResult();
- rv = callback.GetResult(rv);
- EXPECT_THAT(rv, IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
- }
- // Test the client can send application data before the ServerHello comes in.
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTEarlyDataBeforeServerHello) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // Make a 0-RTT Connection. Connect() and Write() complete even though the
- // ServerHello is blocked.
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- // Release the ServerHello. Now reads complete.
- socket->UnblockReadResult();
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int size = ReadAndWait(buf.get(), 4096);
- EXPECT_GT(size, 0);
- EXPECT_EQ('1', buf->data()[size - 1]);
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- // Test that the client sends 1-RTT data if the ServerHello happens to come in
- // before Write() is called. See https://crbug.com/950706.
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTEarlyDataAfterServerHello) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // Make a 0-RTT Connection. Connect() completes even though the ServerHello is
- // blocked.
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- // Wait for the ServerHello to come in and for SSLClientSocket to process it.
- socket->WaitForReadResult();
- socket->UnblockReadResult();
- base::RunLoop().RunUntilIdle();
- // Now write to the socket.
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- // Although the socket was created in early data state and the client never
- // explicitly called ReaD() or ConfirmHandshake(), SSLClientSocketImpl
- // internally consumed the ServerHello and switch keys. The server then
- // responds with '0'.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int size = ReadAndWait(buf.get(), 4096);
- EXPECT_GT(size, 0);
- EXPECT_EQ('0', buf->data()[size - 1]);
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- // Check that 0RTT is confirmed after a Write and Read.
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTConfirmedAfterRead) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // Make a 0-RTT Connection. Connect() and Write() complete even though the
- // ServerHello is blocked.
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- socket->UnblockReadResult();
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int size = ReadAndWait(buf.get(), 4096);
- EXPECT_GT(size, 0);
- EXPECT_EQ('1', buf->data()[size - 1]);
- // After the handshake is confirmed, ConfirmHandshake should return
- // synchronously.
- TestCompletionCallback callback;
- ASSERT_THAT(ssl_socket()->ConfirmHandshake(callback.callback()), IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- // Test that writes wait for the ServerHello once it has reached the early data
- // limit.
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTEarlyDataLimit) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // Make a 0-RTT Connection. Connect() completes even though the ServerHello is
- // blocked.
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- // EmbeddedTestServer uses BoringSSL's hard-coded early data limit, which is
- // below 16k.
- constexpr size_t kRequestSize = 16 * 1024;
- std::string request = "GET /zerortt HTTP/1.0\r\n";
- while (request.size() < kRequestSize) {
- request += "The-Answer-To-Life-The-Universe-And-Everything: 42\r\n";
- }
- request += "\r\n";
- // Writing the large input should not succeed. It is blocked on the
- // ServerHello.
- TestCompletionCallback write_callback;
- auto write_buf = base::MakeRefCounted<StringIOBuffer>(request);
- int write_rv = ssl_socket()->Write(write_buf.get(), request.size(),
- write_callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- ASSERT_THAT(write_rv, IsError(ERR_IO_PENDING));
- // The Write should have issued a read for the ServerHello, so
- // WaitForReadResult has something to wait for.
- socket->WaitForReadResult();
- EXPECT_TRUE(socket->pending_read_result());
- // Queue a read. It should be blocked on the ServerHello.
- TestCompletionCallback read_callback;
- auto read_buf = base::MakeRefCounted<IOBuffer>(4096);
- int read_rv =
- ssl_socket()->Read(read_buf.get(), 4096, read_callback.callback());
- ASSERT_THAT(read_rv, IsError(ERR_IO_PENDING));
- // Also queue a ConfirmHandshake. It should also be blocked on ServerHello.
- TestCompletionCallback confirm_callback;
- int confirm_rv = ssl_socket()->ConfirmHandshake(confirm_callback.callback());
- ASSERT_THAT(confirm_rv, IsError(ERR_IO_PENDING));
- // Double-check the write was not accidentally blocked on the network.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(write_callback.have_result());
- // At this point, the maximum possible number of events are all blocked on the
- // same thing. Release the ServerHello. All three should complete.
- socket->UnblockReadResult();
- EXPECT_EQ(static_cast<int>(request.size()),
- write_callback.GetResult(write_rv));
- EXPECT_THAT(confirm_callback.GetResult(confirm_rv), IsOk());
- int size = read_callback.GetResult(read_rv);
- ASSERT_GT(size, 0);
- EXPECT_EQ('1', read_buf->data()[size - 1]);
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- // When a client socket reaches the 0-RTT early data limit, both Write() and
- // ConfirmHandshake() become blocked on a transport read. Test that
- // CancelReadIfReady() does not interrupt those.
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTEarlyDataLimitCancelReadIfReady) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // Make a 0-RTT Connection. Connect() completes even though the ServerHello is
- // blocked.
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- // EmbeddedTestServer uses BoringSSL's hard-coded early data limit, which is
- // below 16k.
- constexpr size_t kRequestSize = 16 * 1024;
- std::string request = "GET /zerortt HTTP/1.0\r\n";
- while (request.size() < kRequestSize) {
- request += "The-Answer-To-Life-The-Universe-And-Everything: 42\r\n";
- }
- request += "\r\n";
- // Writing the large input should not succeed. It is blocked on the
- // ServerHello.
- TestCompletionCallback write_callback;
- auto write_buf = base::MakeRefCounted<StringIOBuffer>(request);
- int write_rv = ssl_socket()->Write(write_buf.get(), request.size(),
- write_callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- ASSERT_THAT(write_rv, IsError(ERR_IO_PENDING));
- // The Write should have issued a read for the ServerHello, so
- // WaitForReadResult has something to wait for.
- socket->WaitForReadResult();
- EXPECT_TRUE(socket->pending_read_result());
- // Attempt a ReadIfReady(). It should be blocked on the ServerHello.
- TestCompletionCallback read_callback;
- auto read_buf = base::MakeRefCounted<IOBuffer>(4096);
- int read_rv =
- ssl_socket()->ReadIfReady(read_buf.get(), 4096, read_callback.callback());
- ASSERT_THAT(read_rv, IsError(ERR_IO_PENDING));
- // Also queue a ConfirmHandshake. It should also be blocked on ServerHello.
- TestCompletionCallback confirm_callback;
- int confirm_rv = ssl_socket()->ConfirmHandshake(confirm_callback.callback());
- ASSERT_THAT(confirm_rv, IsError(ERR_IO_PENDING));
- // Cancel the ReadIfReady() and release the ServerHello. The remaining
- // operations should complete.
- ASSERT_THAT(ssl_socket()->CancelReadIfReady(), IsOk());
- socket->UnblockReadResult();
- EXPECT_EQ(static_cast<int>(request.size()),
- write_callback.GetResult(write_rv));
- EXPECT_THAT(confirm_callback.GetResult(confirm_rv), IsOk());
- // ReadIfReady() should not complete.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(read_callback.have_result());
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- // After a canceled read, future reads are still possible.
- TestCompletionCallback read_callback2;
- read_rv = read_callback2.GetResult(
- ssl_socket()->Read(read_buf.get(), 4096, read_callback2.callback()));
- ASSERT_GT(read_rv, 0);
- }
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTReject) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- SSLServerConfig server_config;
- server_config.early_data_enabled = false;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
- SetServerConfig(server_config);
- // 0-RTT Connection
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- socket->UnblockReadResult();
- // Expect early data to be rejected.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int rv = ReadAndWait(buf.get(), 4096);
- EXPECT_EQ(ERR_EARLY_DATA_REJECTED, rv);
- rv = WriteAndWait(kRequest);
- EXPECT_EQ(ERR_EARLY_DATA_REJECTED, rv);
- // Retrying the connection should succeed.
- socket = MakeClient(true);
- ASSERT_THAT(Connect(), IsOk());
- ASSERT_THAT(MakeHTTPRequest(ssl_socket()), IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- }
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTWrongVersion) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- SetServerConfig(server_config);
- // 0-RTT Connection
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- socket->UnblockReadResult();
- // Expect early data to be rejected because the TLS version was incorrect.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int rv = ReadAndWait(buf.get(), 4096);
- EXPECT_EQ(ERR_WRONG_VERSION_ON_EARLY_DATA, rv);
- rv = WriteAndWait(kRequest);
- EXPECT_EQ(ERR_WRONG_VERSION_ON_EARLY_DATA, rv);
- // Retrying the connection should succeed.
- socket = MakeClient(true);
- ASSERT_THAT(Connect(), IsOk());
- ASSERT_THAT(MakeHTTPRequest(ssl_socket()), IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- }
- // Test that the ConfirmHandshake successfully completes the handshake and that
- // it blocks until the server's leg has been received.
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTConfirmHandshake) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // 0-RTT Connection
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- // The ServerHello is blocked, so ConfirmHandshake should not complete.
- TestCompletionCallback callback;
- ASSERT_EQ(ERR_IO_PENDING,
- ssl_socket()->ConfirmHandshake(callback.callback()));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(callback.have_result());
- // Release the ServerHello. ConfirmHandshake now completes.
- socket->UnblockReadResult();
- ASSERT_THAT(callback.GetResult(ERR_IO_PENDING), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int size = ReadAndWait(buf.get(), 4096);
- EXPECT_GT(size, 0);
- EXPECT_EQ('0', buf->data()[size - 1]);
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- // Test that an early read does not break during zero RTT.
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTReadBeforeWrite) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // Make a 0-RTT Connection. Connect() completes even though the ServerHello is
- // blocked.
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- // Read() does not make progress.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- TestCompletionCallback read_callback;
- ASSERT_EQ(ERR_IO_PENDING,
- ssl_socket()->Read(buf.get(), 4096, read_callback.callback()));
- // Write() completes, even though reads are blocked.
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- // Release the ServerHello, etc. The Read() now completes.
- socket->UnblockReadResult();
- int size = read_callback.GetResult(ERR_IO_PENDING);
- EXPECT_GT(size, 0);
- EXPECT_EQ('1', buf->data()[size - 1]);
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTDoubleConfirmHandshake) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // 0-RTT Connection
- MakeClient(true);
- ASSERT_THAT(Connect(), IsOk());
- TestCompletionCallback callback;
- ASSERT_THAT(
- callback.GetResult(ssl_socket()->ConfirmHandshake(callback.callback())),
- IsOk());
- // After the handshake is confirmed, ConfirmHandshake should return
- // synchronously.
- ASSERT_THAT(ssl_socket()->ConfirmHandshake(callback.callback()), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int size = ReadAndWait(buf.get(), 4096);
- EXPECT_GT(size, 0);
- EXPECT_EQ('0', buf->data()[size - 1]);
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- TEST_F(SSLClientSocketZeroRTTTest, ZeroRTTParallelReadConfirm) {
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // 0-RTT Connection
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- // The ServerHello is blocked, so ConfirmHandshake should not complete.
- TestCompletionCallback callback;
- ASSERT_EQ(ERR_IO_PENDING,
- ssl_socket()->ConfirmHandshake(callback.callback()));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(callback.have_result());
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- TestCompletionCallback read_callback;
- ASSERT_EQ(ERR_IO_PENDING,
- ssl_socket()->Read(buf.get(), 4096, read_callback.callback()));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(read_callback.have_result());
- // Release the ServerHello. ConfirmHandshake now completes.
- socket->UnblockReadResult();
- ASSERT_THAT(callback.WaitForResult(), IsOk());
- int result = read_callback.WaitForResult();
- EXPECT_GT(result, 0);
- EXPECT_EQ('1', buf->data()[result - 1]);
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- }
- TEST_P(SSLClientSocketReadTest, IdleAfterRead) {
- // Set up a TCP server.
- TCPServerSocket server_listener(nullptr, NetLogSource());
- ASSERT_THAT(
- server_listener.Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0), 1),
- IsOk());
- IPEndPoint server_address;
- ASSERT_THAT(server_listener.GetLocalAddress(&server_address), IsOk());
- // Connect a TCP client and server socket.
- TestCompletionCallback server_callback;
- std::unique_ptr<StreamSocket> server_transport;
- int server_rv =
- server_listener.Accept(&server_transport, server_callback.callback());
- TestCompletionCallback client_callback;
- auto client_transport = std::make_unique<TCPClientSocket>(
- AddressList(server_address), nullptr, nullptr, nullptr, NetLogSource());
- int client_rv = client_transport->Connect(client_callback.callback());
- EXPECT_THAT(server_callback.GetResult(server_rv), IsOk());
- EXPECT_THAT(client_callback.GetResult(client_rv), IsOk());
- // Set up an SSL server.
- base::FilePath certs_dir = GetTestCertsDirectory();
- scoped_refptr<net::X509Certificate> cert =
- ImportCertFromFile(certs_dir, "ok_cert.pem");
- ASSERT_TRUE(cert);
- bssl::UniquePtr<EVP_PKEY> pkey =
- key_util::LoadEVP_PKEYFromPEM(certs_dir.AppendASCII("ok_cert.pem"));
- ASSERT_TRUE(pkey);
- std::unique_ptr<crypto::RSAPrivateKey> key =
- crypto::RSAPrivateKey::CreateFromKey(pkey.get());
- ASSERT_TRUE(key);
- std::unique_ptr<SSLServerContext> server_context =
- CreateSSLServerContext(cert.get(), *key.get(), GetServerConfig());
- // Complete the SSL handshake on both sides.
- std::unique_ptr<SSLClientSocket> client(CreateSSLClientSocket(
- std::move(client_transport), HostPortPair::FromIPEndPoint(server_address),
- SSLConfig()));
- std::unique_ptr<SSLServerSocket> server(
- server_context->CreateSSLServerSocket(std::move(server_transport)));
- server_rv = server->Handshake(server_callback.callback());
- client_rv = client->Connect(client_callback.callback());
- EXPECT_THAT(server_callback.GetResult(server_rv), IsOk());
- EXPECT_THAT(client_callback.GetResult(client_rv), IsOk());
- // Write a single record on the server.
- scoped_refptr<IOBuffer> write_buf = base::MakeRefCounted<StringIOBuffer>("a");
- server_rv = server->Write(write_buf.get(), 1, server_callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- // Read that record on the server, but with a much larger buffer than
- // necessary.
- scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(1024);
- client_rv =
- Read(client.get(), read_buf.get(), 1024, client_callback.callback());
- EXPECT_EQ(1, server_callback.GetResult(server_rv));
- EXPECT_EQ(1, WaitForReadCompletion(client.get(), read_buf.get(), 1024,
- &client_callback, client_rv));
- // At this point the client socket should be idle.
- EXPECT_TRUE(client->IsConnectedAndIdle());
- }
- // Test that certificate errors are properly reported when the underlying
- // transport is itself a TLS connection, such as when tunneling over an HTTPS
- // proxy. See https://crbug.com/959305.
- TEST_F(SSLClientSocketTest, SSLOverSSLBadCertificate) {
- // Load a pair of certificates.
- base::FilePath certs_dir = GetTestCertsDirectory();
- scoped_refptr<net::X509Certificate> ok_cert =
- ImportCertFromFile(certs_dir, "ok_cert.pem");
- ASSERT_TRUE(ok_cert);
- bssl::UniquePtr<EVP_PKEY> ok_pkey =
- key_util::LoadEVP_PKEYFromPEM(certs_dir.AppendASCII("ok_cert.pem"));
- ASSERT_TRUE(ok_pkey);
- scoped_refptr<net::X509Certificate> expired_cert =
- ImportCertFromFile(certs_dir, "expired_cert.pem");
- ASSERT_TRUE(expired_cert);
- bssl::UniquePtr<EVP_PKEY> expired_pkey =
- key_util::LoadEVP_PKEYFromPEM(certs_dir.AppendASCII("expired_cert.pem"));
- ASSERT_TRUE(expired_pkey);
- CertVerifyResult expired_result;
- expired_result.verified_cert = expired_cert;
- expired_result.cert_status = CERT_STATUS_DATE_INVALID;
- cert_verifier_->AddResultForCert(expired_cert, expired_result,
- ERR_CERT_DATE_INVALID);
- // Set up a TCP server.
- TCPServerSocket server_listener(nullptr, NetLogSource());
- ASSERT_THAT(
- server_listener.Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0), 1),
- IsOk());
- IPEndPoint server_address;
- ASSERT_THAT(server_listener.GetLocalAddress(&server_address), IsOk());
- // Connect a TCP client and server socket.
- TestCompletionCallback server_callback;
- std::unique_ptr<StreamSocket> server_transport;
- int server_rv =
- server_listener.Accept(&server_transport, server_callback.callback());
- TestCompletionCallback client_callback;
- auto client_transport = std::make_unique<TCPClientSocket>(
- AddressList(server_address), nullptr, nullptr, nullptr, NetLogSource());
- int client_rv = client_transport->Connect(client_callback.callback());
- ASSERT_THAT(server_callback.GetResult(server_rv), IsOk());
- ASSERT_THAT(client_callback.GetResult(client_rv), IsOk());
- // Set up a pair of SSL servers.
- std::unique_ptr<crypto::RSAPrivateKey> ok_key =
- crypto::RSAPrivateKey::CreateFromKey(ok_pkey.get());
- ASSERT_TRUE(ok_key);
- std::unique_ptr<SSLServerContext> ok_server_context =
- CreateSSLServerContext(ok_cert.get(), *ok_key.get(), SSLServerConfig());
- std::unique_ptr<crypto::RSAPrivateKey> expired_key =
- crypto::RSAPrivateKey::CreateFromKey(expired_pkey.get());
- ASSERT_TRUE(expired_key);
- std::unique_ptr<SSLServerContext> expired_server_context =
- CreateSSLServerContext(expired_cert.get(), *expired_key.get(),
- SSLServerConfig());
- // Complete the proxy SSL handshake with ok_cert.pem. This should succeed.
- std::unique_ptr<SSLClientSocket> client =
- CreateSSLClientSocket(std::move(client_transport),
- HostPortPair("proxy.test", 443), SSLConfig());
- std::unique_ptr<SSLServerSocket> server =
- ok_server_context->CreateSSLServerSocket(std::move(server_transport));
- client_rv = client->Connect(client_callback.callback());
- server_rv = server->Handshake(server_callback.callback());
- ASSERT_THAT(client_callback.GetResult(client_rv), IsOk());
- ASSERT_THAT(server_callback.GetResult(server_rv), IsOk());
- // Run the tunneled SSL handshake on with expired_cert.pem. This should fail.
- client = CreateSSLClientSocket(std::move(client),
- HostPortPair("server.test", 443), SSLConfig());
- server = expired_server_context->CreateSSLServerSocket(std::move(server));
- client_rv = client->Connect(client_callback.callback());
- server_rv = server->Handshake(server_callback.callback());
- // The client should observe the bad certificate error.
- EXPECT_THAT(client_callback.GetResult(client_rv),
- IsError(ERR_CERT_DATE_INVALID));
- SSLInfo ssl_info;
- ASSERT_TRUE(client->GetSSLInfo(&ssl_info));
- EXPECT_EQ(ssl_info.cert_status, expired_result.cert_status);
- // TODO(https://crbug.com/912383): The server sees
- // ERR_BAD_SSL_CLIENT_AUTH_CERT because its peer (the client) alerts it with
- // bad_certificate. The alert-mapping code assumes it is running on a client,
- // so it translates bad_certificate to ERR_BAD_SSL_CLIENT_AUTH_CERT, which
- // shouldn't be the error for a bad server certificate.
- EXPECT_THAT(server_callback.GetResult(server_rv),
- IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
- }
- TEST_F(SSLClientSocketTest, Tag) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- auto transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, NetLog::Get(), NetLogSource());
- auto tagging_sock =
- std::make_unique<MockTaggingStreamSocket>(std::move(transport));
- auto* tagging_sock_ptr = tagging_sock.get();
- // |sock| takes ownership of |tagging_sock|, but keep a
- // non-owning pointer to it.
- std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
- std::move(tagging_sock), host_port_pair(), SSLConfig()));
- EXPECT_EQ(tagging_sock_ptr->tag(), SocketTag());
- #if BUILDFLAG(IS_ANDROID)
- SocketTag tag(0x12345678, 0x87654321);
- sock->ApplySocketTag(tag);
- EXPECT_EQ(tagging_sock_ptr->tag(), tag);
- #endif // BUILDFLAG(IS_ANDROID)
- }
- TEST_F(SSLClientSocketTest, ECH) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
- SSLServerConfig server_config;
- SSLConfig client_config;
- server_config.ech_keys = MakeTestEchKeys(
- "public.example", /*max_name_len=*/64, &client_config.ech_config_list);
- ASSERT_TRUE(server_config.ech_keys);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // Connecting with the client should use ECH.
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- SSLInfo ssl_info;
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
- EXPECT_TRUE(ssl_info.encrypted_client_hello);
- // TLS 1.3 causes the ticket to arrive later. Use the socket to ensure we have
- // a ticket. This also populates the SSLInfo from the server.
- EXPECT_THAT(MakeHTTPRequest(sock_.get(), "/ssl-info"), IsOk());
- absl::optional<SSLInfo> server_ssl_info = LastSSLInfoFromServer();
- ASSERT_TRUE(server_ssl_info);
- EXPECT_TRUE(server_ssl_info->encrypted_client_hello);
- // Reconnect. ECH should not interfere with resumption.
- sock_.reset();
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- EXPECT_TRUE(ssl_info.encrypted_client_hello);
- // Check SSLInfo from the server.
- EXPECT_THAT(MakeHTTPRequest(sock_.get(), "/ssl-info"), IsOk());
- server_ssl_info = LastSSLInfoFromServer();
- ASSERT_TRUE(server_ssl_info);
- EXPECT_TRUE(server_ssl_info->encrypted_client_hello);
- // Connecting without ECH should not report ECH was used.
- client_config.ech_config_list.clear();
- sock_.reset();
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
- EXPECT_FALSE(ssl_info.encrypted_client_hello);
- // Check SSLInfo from the server.
- EXPECT_THAT(MakeHTTPRequest(sock_.get(), "/ssl-info"), IsOk());
- server_ssl_info = LastSSLInfoFromServer();
- ASSERT_TRUE(server_ssl_info);
- EXPECT_FALSE(server_ssl_info->encrypted_client_hello);
- }
- // Test that, on key mismatch, the public name can be used to authenticate
- // replacement keys.
- TEST_F(SSLClientSocketTest, ECHWrongKeys) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
- static const char kPublicName[] = "public.example";
- std::vector<uint8_t> ech_config_list1, ech_config_list2;
- bssl::UniquePtr<SSL_ECH_KEYS> keys1 =
- MakeTestEchKeys(kPublicName, /*max_name_len=*/64, &ech_config_list1);
- ASSERT_TRUE(keys1);
- bssl::UniquePtr<SSL_ECH_KEYS> keys2 =
- MakeTestEchKeys(kPublicName, /*max_name_len=*/64, &ech_config_list2);
- ASSERT_TRUE(keys2);
- // Configure the client and server with different keys.
- SSLServerConfig server_config;
- server_config.ech_keys = std::move(keys1);
- SSLConfig client_config;
- client_config.ech_config_list = std::move(ech_config_list2);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // Verify the fallback handshake verifies the certificate against the public
- // name.
- cert_verifier_->set_default_result(ERR_CERT_INVALID);
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- CertVerifyResult verify_result;
- verify_result.verified_cert = server_cert;
- cert_verifier_->AddResultForCertAndHost(server_cert, kPublicName,
- verify_result, OK);
- // Connecting with the client should report ECH was not negotiated.
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsError(ERR_ECH_NOT_NEGOTIATED));
- // The server's keys are available as retry keys.
- EXPECT_EQ(ech_config_list1, sock_->GetECHRetryConfigs());
- }
- // Test that, if the server does not support ECH, it can securely report this
- // via the public name. This allows recovery if the server needed to
- // rollback ECH support.
- TEST_F(SSLClientSocketTest, ECHSecurelyDisabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
- static const char kPublicName[] = "public.example";
- std::vector<uint8_t> ech_config_list;
- bssl::UniquePtr<SSL_ECH_KEYS> keys =
- MakeTestEchKeys(kPublicName, /*max_name_len=*/64, &ech_config_list);
- ASSERT_TRUE(keys);
- // The server does not have keys configured.
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- // However it can authenticate for kPublicName.
- cert_verifier_->set_default_result(ERR_CERT_INVALID);
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- CertVerifyResult verify_result;
- verify_result.verified_cert = server_cert;
- cert_verifier_->AddResultForCertAndHost(server_cert, kPublicName,
- verify_result, OK);
- // Connecting with the client should report ECH was not negotiated.
- SSLConfig client_config;
- client_config.ech_config_list = std::move(ech_config_list);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsError(ERR_ECH_NOT_NEGOTIATED));
- // The retry config is empty, meaning the server has securely reported that
- // ECH is disabled
- EXPECT_TRUE(sock_->GetECHRetryConfigs().empty());
- }
- // The same as the above, but testing that it also works in TLS 1.2, which
- // otherwise does not support ECH.
- TEST_F(SSLClientSocketTest, ECHSecurelyDisabledTLS12) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
- static const char kPublicName[] = "public.example";
- std::vector<uint8_t> ech_config_list;
- bssl::UniquePtr<SSL_ECH_KEYS> keys =
- MakeTestEchKeys(kPublicName, /*max_name_len=*/64, &ech_config_list);
- ASSERT_TRUE(keys);
- // The server does not have keys configured.
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // However it can authenticate for kPublicName.
- cert_verifier_->set_default_result(ERR_CERT_INVALID);
- scoped_refptr<X509Certificate> server_cert =
- embedded_test_server()->GetCertificate();
- CertVerifyResult verify_result;
- verify_result.verified_cert = server_cert;
- cert_verifier_->AddResultForCertAndHost(server_cert, kPublicName,
- verify_result, OK);
- // Connecting with the client should report ECH was not negotiated.
- SSLConfig client_config;
- client_config.ech_config_list = std::move(ech_config_list);
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsError(ERR_ECH_NOT_NEGOTIATED));
- // The retry config is empty, meaning the server has securely reported that
- // ECH is disabled
- EXPECT_TRUE(sock_->GetECHRetryConfigs().empty());
- }
- // Test that the ECH fallback handshake rejects bad certificates.
- TEST_F(SSLClientSocketTest, ECHFallbackBadCert) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
- static const char kPublicName[] = "public.example";
- std::vector<uint8_t> ech_config_list1, ech_config_list2;
- bssl::UniquePtr<SSL_ECH_KEYS> keys1 =
- MakeTestEchKeys(kPublicName, /*max_name_len=*/64, &ech_config_list1);
- ASSERT_TRUE(keys1);
- bssl::UniquePtr<SSL_ECH_KEYS> keys2 =
- MakeTestEchKeys(kPublicName, /*max_name_len=*/64, &ech_config_list2);
- ASSERT_TRUE(keys2);
- // Configure the client and server with different keys.
- SSLServerConfig server_config;
- server_config.ech_keys = std::move(keys1);
- SSLConfig client_config;
- client_config.ech_config_list = std::move(ech_config_list2);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // Configure the client to reject the certificate for the public name (or any
- // other name).
- cert_verifier_->set_default_result(ERR_CERT_INVALID);
- // Connecting with the client will fail with a fatal error.
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsError(ERR_ECH_FALLBACK_CERTIFICATE_INVALID));
- }
- TEST_F(SSLClientSocketTest, InvalidECHConfigList) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- // If the ECHConfigList cannot be parsed at all, report an error to the
- // caller.
- SSLConfig client_config;
- client_config.ech_config_list = {0x00};
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsError(ERR_INVALID_ECH_CONFIG_LIST));
- }
- // Test that, if no ECHConfigList is available, the client sends ECH GREASE.
- TEST_F(SSLClientSocketTest, ECHGreaseEnabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kEncryptedClientHello);
- // Configure the server to expect an ECH extension.
- bool ran_callback = false;
- SSLServerConfig server_config;
- server_config.client_hello_callback_for_testing =
- base::BindLambdaForTesting([&](const SSL_CLIENT_HELLO* client_hello) {
- const uint8_t* data;
- size_t len;
- EXPECT_TRUE(SSL_early_callback_ctx_extension_get(
- client_hello, TLSEXT_TYPE_encrypted_client_hello, &data, &len));
- ran_callback = true;
- return true;
- });
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(ran_callback);
- }
- // Test that, if the feature flag is disabled, the client does not send ECH
- // GREASE.
- TEST_F(SSLClientSocketTest, ECHGreaseDisabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndDisableFeature(features::kEncryptedClientHello);
- // Configure the server not to expect an ECH extension.
- bool ran_callback = false;
- SSLServerConfig server_config;
- server_config.client_hello_callback_for_testing =
- base::BindLambdaForTesting([&](const SSL_CLIENT_HELLO* client_hello) {
- const uint8_t* data;
- size_t len;
- EXPECT_FALSE(SSL_early_callback_ctx_extension_get(
- client_hello, TLSEXT_TYPE_encrypted_client_hello, &data, &len));
- ran_callback = true;
- return true;
- });
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
- EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(ran_callback);
- }
- struct SSLHandshakeDetailsParams {
- bool alpn;
- bool early_data;
- uint16_t version;
- SSLHandshakeDetails expected_initial;
- SSLHandshakeDetails expected_resume;
- };
- const SSLHandshakeDetailsParams kSSLHandshakeDetailsParams[] = {
- // TLS 1.0 and 1.1 never do False Start.
- {false /* no ALPN */, false /* no early data */, SSL_PROTOCOL_VERSION_TLS1,
- SSLHandshakeDetails::kTLS12Full, SSLHandshakeDetails::kTLS12Resume},
- {false /* no ALPN */, false /* no early data */,
- SSL_PROTOCOL_VERSION_TLS1_1, SSLHandshakeDetails::kTLS12Full,
- SSLHandshakeDetails::kTLS12Resume},
- // TLS 1.2 does False Start if ALPN is enabled.
- {false /* no ALPN */, false /* no early data */,
- SSL_PROTOCOL_VERSION_TLS1_2, SSLHandshakeDetails::kTLS12Full,
- SSLHandshakeDetails::kTLS12Resume},
- {true /* ALPN */, false /* no early data */, SSL_PROTOCOL_VERSION_TLS1_2,
- SSLHandshakeDetails::kTLS12FalseStart, SSLHandshakeDetails::kTLS12Resume},
- // TLS 1.3 supports full handshakes, resumption, and 0-RTT.
- {false /* no ALPN */, false /* no early data */,
- SSL_PROTOCOL_VERSION_TLS1_3, SSLHandshakeDetails::kTLS13Full,
- SSLHandshakeDetails::kTLS13Resume},
- {false /* no ALPN */, true /* early data */, SSL_PROTOCOL_VERSION_TLS1_3,
- SSLHandshakeDetails::kTLS13Full, SSLHandshakeDetails::kTLS13Early},
- };
- class SSLHandshakeDetailsTest
- : public SSLClientSocketTest,
- public ::testing::WithParamInterface<SSLHandshakeDetailsParams> {};
- INSTANTIATE_TEST_SUITE_P(All,
- SSLHandshakeDetailsTest,
- ValuesIn(kSSLHandshakeDetailsParams));
- TEST_P(SSLHandshakeDetailsTest, Metrics) {
- // Enable all test features in the server.
- SSLServerConfig server_config;
- server_config.version_min = SSL_PROTOCOL_VERSION_TLS1;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
- server_config.early_data_enabled = true;
- server_config.alpn_protos = {kProtoHTTP11};
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLContextConfig client_context_config;
- client_context_config.version_min = GetParam().version;
- client_context_config.version_max = GetParam().version;
- ssl_config_service_->UpdateSSLConfigAndNotify(client_context_config);
- SSLConfig client_config;
- client_config.version_min_override = GetParam().version;
- client_config.version_max_override = GetParam().version;
- client_config.early_data_enabled = GetParam().early_data;
- if (GetParam().alpn) {
- client_config.alpn_protos = {kProtoHTTP11};
- }
- SSLVersion version;
- switch (GetParam().version) {
- case SSL_PROTOCOL_VERSION_TLS1:
- version = SSL_CONNECTION_VERSION_TLS1;
- break;
- case SSL_PROTOCOL_VERSION_TLS1_1:
- version = SSL_CONNECTION_VERSION_TLS1_1;
- break;
- case SSL_PROTOCOL_VERSION_TLS1_2:
- version = SSL_CONNECTION_VERSION_TLS1_2;
- break;
- case SSL_PROTOCOL_VERSION_TLS1_3:
- version = SSL_CONNECTION_VERSION_TLS1_3;
- break;
- default:
- FAIL() << GetParam().version;
- }
- // Make the initial connection.
- {
- base::HistogramTester histograms;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- // Sanity-check the socket matches the test parameters.
- SSLInfo info;
- ASSERT_TRUE(sock_->GetSSLInfo(&info));
- EXPECT_EQ(version, SSLConnectionStatusToVersion(info.connection_status));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, info.handshake_type);
- EXPECT_EQ(GetParam().alpn, sock_->WasAlpnNegotiated());
- histograms.ExpectUniqueSample("Net.SSLHandshakeDetails",
- GetParam().expected_initial, 1);
- // TLS 1.2 with False Start and TLS 1.3 cause the ticket to arrive later, so
- // use the socket to ensure the session ticket has been picked up.
- EXPECT_THAT(MakeHTTPRequest(sock_.get()), IsOk());
- }
- // Make a resumption connection.
- {
- base::HistogramTester histograms;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- // Sanity-check the socket matches the test parameters.
- SSLInfo info;
- ASSERT_TRUE(sock_->GetSSLInfo(&info));
- EXPECT_EQ(version, SSLConnectionStatusToVersion(info.connection_status));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, info.handshake_type);
- EXPECT_EQ(GetParam().alpn, sock_->WasAlpnNegotiated());
- histograms.ExpectUniqueSample("Net.SSLHandshakeDetails",
- GetParam().expected_resume, 1);
- }
- }
- TEST_F(SSLClientSocketZeroRTTTest, EarlyDataReasonNewSession) {
- const char kReasonHistogram[] = "Net.SSLHandshakeEarlyDataReason";
- ASSERT_TRUE(StartServer());
- base::HistogramTester histograms;
- ASSERT_TRUE(RunInitialConnection());
- histograms.ExpectUniqueSample(kReasonHistogram,
- ssl_early_data_no_session_offered, 1);
- }
- // Test 0-RTT logging when the server declines to resume a connection.
- TEST_F(SSLClientSocketZeroRTTTest, EarlyDataReasonNoResume) {
- const char kReasonHistogram[] = "Net.SSLHandshakeEarlyDataReason";
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- SSLServerConfig server_config;
- server_config.early_data_enabled = false;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
- SetServerConfig(server_config);
- base::HistogramTester histograms;
- // 0-RTT Connection
- FakeBlockingStreamSocket* socket = MakeClient(true);
- socket->BlockReadResult();
- ASSERT_THAT(Connect(), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- socket->UnblockReadResult();
- // Expect early data to be rejected.
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int rv = ReadAndWait(buf.get(), 4096);
- EXPECT_EQ(ERR_EARLY_DATA_REJECTED, rv);
- histograms.ExpectUniqueSample(kReasonHistogram,
- ssl_early_data_session_not_resumed, 1);
- }
- // Test 0-RTT logging in the standard ConfirmHandshake-after-acceptance case.
- TEST_F(SSLClientSocketZeroRTTTest, EarlyDataReasonZeroRTT) {
- const char kReasonHistogram[] = "Net.SSLHandshakeEarlyDataReason";
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // 0-RTT Connection
- base::HistogramTester histograms;
- MakeClient(true);
- ASSERT_THAT(Connect(), IsOk());
- TestCompletionCallback callback;
- ASSERT_THAT(
- callback.GetResult(ssl_socket()->ConfirmHandshake(callback.callback())),
- IsOk());
- base::RunLoop().RunUntilIdle();
- histograms.ExpectUniqueSample(kReasonHistogram, ssl_early_data_accepted, 1);
- }
- // Check that we're correctly logging 0-rtt success when the handshake
- // concludes during a Read.
- TEST_F(SSLClientSocketZeroRTTTest, EarlyDataReasonReadServerHello) {
- const char kReasonHistogram[] = "Net.SSLHandshakeEarlyDataReason";
- ASSERT_TRUE(StartServer());
- ASSERT_TRUE(RunInitialConnection());
- // 0-RTT Connection
- base::HistogramTester histograms;
- MakeClient(true);
- ASSERT_THAT(Connect(), IsOk());
- constexpr base::StringPiece kRequest = "GET /zerortt HTTP/1.0\r\n\r\n";
- EXPECT_EQ(static_cast<int>(kRequest.size()), WriteAndWait(kRequest));
- scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(4096);
- int size = ReadAndWait(buf.get(), 4096);
- EXPECT_GT(size, 0);
- EXPECT_EQ('1', buf->data()[size - 1]);
- // 0-RTT metrics are logged on a PostTask, so if Read returns synchronously,
- // it is possible the metrics haven't been picked up yet.
- base::RunLoop().RunUntilIdle();
- SSLInfo ssl_info;
- ASSERT_TRUE(GetSSLInfo(&ssl_info));
- EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type);
- histograms.ExpectUniqueSample(kReasonHistogram, ssl_early_data_accepted, 1);
- }
- TEST_F(SSLClientSocketTest, VersionMaxOverride) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // Connecting normally uses the global configuration.
- SSLConfig config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
- EXPECT_THAT(rv, IsOk());
- SSLInfo info;
- ASSERT_TRUE(sock_->GetSSLInfo(&info));
- EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_3,
- SSLConnectionStatusToVersion(info.connection_status));
- // Individual sockets may override the maximum version.
- config.version_max_override = SSL_PROTOCOL_VERSION_TLS1_2;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
- EXPECT_THAT(rv, IsOk());
- ASSERT_TRUE(sock_->GetSSLInfo(&info));
- EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_2,
- SSLConnectionStatusToVersion(info.connection_status));
- }
- TEST_F(SSLClientSocketTest, VersionMinOverride) {
- SSLServerConfig server_config;
- server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // Connecting normally uses the global configuration.
- SSLConfig config;
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
- EXPECT_THAT(rv, IsOk());
- SSLInfo info;
- ASSERT_TRUE(sock_->GetSSLInfo(&info));
- EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_2,
- SSLConnectionStatusToVersion(info.connection_status));
- // Individual sockets may also override the minimum version.
- config.version_min_override = SSL_PROTOCOL_VERSION_TLS1_3;
- config.version_max_override = SSL_PROTOCOL_VERSION_TLS1_3;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
- EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
- }
- // Basic test of CancelReadIfReady works.
- TEST_F(SSLClientSocketTest, CancelReadIfReady) {
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, SSLServerConfig()));
- // Connect with a FakeBlockingStreamSocket.
- auto real_transport = std::make_unique<TCPClientSocket>(
- addr(), nullptr, nullptr, nullptr, NetLogSource());
- auto transport =
- std::make_unique<FakeBlockingStreamSocket>(std::move(real_transport));
- FakeBlockingStreamSocket* raw_transport = transport.get();
- TestCompletionCallback callback;
- ASSERT_THAT(callback.GetResult(transport->Connect(callback.callback())),
- IsOk());
- // Complete the handshake. Disable the post-handshake peek so that, after the
- // handshake, there are no pending reads on the transport.
- SSLConfig config;
- config.disable_post_handshake_peek_for_testing = true;
- auto sock =
- CreateSSLClientSocket(std::move(transport), host_port_pair(), config);
- ASSERT_THAT(callback.GetResult(sock->Connect(callback.callback())), IsOk());
- // Block the socket and wait for some data to arrive from the server.
- raw_transport->BlockReadResult();
- auto write_buf =
- base::MakeRefCounted<StringIOBuffer>("GET / HTTP/1.0\r\n\r\n");
- ASSERT_EQ(callback.GetResult(sock->Write(write_buf.get(), write_buf->size(),
- callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS)),
- write_buf->size());
- // ReadIfReady() should not read anything because the socket is blocked.
- bool callback_called = false;
- auto read_buf = base::MakeRefCounted<IOBuffer>(100);
- int rv = sock->ReadIfReady(
- read_buf.get(), 100,
- base::BindLambdaForTesting([&](int rv) { callback_called = true; }));
- ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
- // Cancel ReadIfReady() and unblock the socket.
- ASSERT_THAT(sock->CancelReadIfReady(), IsOk());
- raw_transport->WaitForReadResult();
- raw_transport->UnblockReadResult();
- base::RunLoop().RunUntilIdle();
- // Although data is now available, the callback should not have been called.
- EXPECT_FALSE(callback_called);
- // Future reads on the socket should still work. The data should be
- // synchronously available.
- EXPECT_GT(
- callback.GetResult(sock->Read(read_buf.get(), 100, callback.callback())),
- 0);
- }
- // Test that the server_name extension (SNI) is sent on DNS names, and not IP
- // literals.
- TEST_F(SSLClientSocketTest, ServerName) {
- absl::optional<std::string> got_server_name;
- bool ran_callback = false;
- auto reset_callback_state = [&] {
- got_server_name = absl::nullopt;
- ran_callback = false;
- };
- // Start a server which records the server name.
- SSLServerConfig server_config;
- server_config.client_hello_callback_for_testing =
- base::BindLambdaForTesting([&](const SSL_CLIENT_HELLO* client_hello) {
- const char* server_name =
- SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name);
- if (server_name) {
- got_server_name = server_name;
- } else {
- got_server_name = absl::nullopt;
- }
- ran_callback = true;
- return true;
- });
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- // The client should send the server_name extension for DNS names.
- uint16_t port = host_port_pair().port();
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(
- SSLConfig(), HostPortPair("example.com", port), &rv));
- ASSERT_THAT(rv, IsOk());
- EXPECT_TRUE(ran_callback);
- EXPECT_EQ(got_server_name, "example.com");
- // The client should not send the server_name extension for IPv4 and IPv6
- // literals. See https://crbug.com/500981.
- reset_callback_state();
- ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(
- SSLConfig(), HostPortPair("1.2.3.4", port), &rv));
- ASSERT_THAT(rv, IsOk());
- EXPECT_TRUE(ran_callback);
- EXPECT_EQ(got_server_name, absl::nullopt);
- reset_callback_state();
- ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(
- SSLConfig(), HostPortPair("::1", port), &rv));
- ASSERT_THAT(rv, IsOk());
- EXPECT_TRUE(ran_callback);
- EXPECT_EQ(got_server_name, absl::nullopt);
- reset_callback_state();
- ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(
- SSLConfig(), HostPortPair("2001:db8::42", port), &rv));
- ASSERT_THAT(rv, IsOk());
- EXPECT_TRUE(ran_callback);
- EXPECT_EQ(got_server_name, absl::nullopt);
- }
- class SSLClientSocketAlpsTest
- : public SSLClientSocketTest,
- public ::testing::WithParamInterface<std::tuple<bool, bool>> {
- public:
- SSLClientSocketAlpsTest()
- : client_alps_enabled_(std::get<0>(GetParam())),
- server_alps_enabled_(std::get<1>(GetParam())) {}
- ~SSLClientSocketAlpsTest() override = default;
- const bool client_alps_enabled_;
- const bool server_alps_enabled_;
- };
- INSTANTIATE_TEST_SUITE_P(All, SSLClientSocketAlpsTest, Combine(Bool(), Bool()));
- TEST_P(SSLClientSocketAlpsTest, Alps) {
- const std::string server_data = "server sends some test data";
- const std::string client_data = "client also sends some data";
- SSLServerConfig server_config;
- server_config.alpn_protos = {kProtoHTTP2};
- if (server_alps_enabled_) {
- server_config.application_settings[kProtoHTTP2] =
- std::vector<uint8_t>(server_data.begin(), server_data.end());
- }
- ASSERT_TRUE(
- StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
- SSLConfig client_config;
- client_config.alpn_protos = {kProtoHTTP2};
- if (client_alps_enabled_) {
- client_config.application_settings[kProtoHTTP2] =
- std::vector<uint8_t>(client_data.begin(), client_data.end());
- }
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv));
- EXPECT_THAT(rv, IsOk());
- SSLInfo info;
- ASSERT_TRUE(sock_->GetSSLInfo(&info));
- EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_3,
- SSLConnectionStatusToVersion(info.connection_status));
- EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, info.handshake_type);
- EXPECT_EQ(true, sock_->WasAlpnNegotiated());
- EXPECT_EQ(kProtoHTTP2, sock_->GetNegotiatedProtocol());
- // ALPS is negotiated only if ALPS is enabled both on client and server.
- const auto alps_data_received_by_client = sock_->GetPeerApplicationSettings();
- if (client_alps_enabled_ && server_alps_enabled_) {
- ASSERT_TRUE(alps_data_received_by_client.has_value());
- EXPECT_EQ(server_data, alps_data_received_by_client.value());
- } else {
- EXPECT_FALSE(alps_data_received_by_client.has_value());
- }
- }
- } // namespace net
|