Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file vmm_tls.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101(* (c) 2018 Hannes Mehnert, all rights reserved *)let(let*)=Result.bind(* we skip all non-albatross certificates *)letcert_namecert=matchX509.Extension.(find(UnsupportedVmm_asn.oid)(X509.Certificate.extensionscert))with|None->OkNone|Some(_,data)->matchX509.(Distinguished_name.common_name(Certificate.subjectcert))with|Somename->Ok(Somename)|None->matchVmm_asn.of_cert_extensiondatawith|Error(`Msg_)->Error(`Msg"couldn't parse albatross extension")|Ok(_,`Policy_cmdpc)->beginmatchpcwith|`Policy_add_->Error(`Msg"policy add may not have an empty name")|`Policy_remove->Error(`Msg"policy remove may not have an empty name")|`Policy_info->OkNoneend|Ok(_,`Block_cmdbc)->beginmatchbcwith|`Block_add_->Error(`Msg"block add may not have an empty name")|`Block_remove->Error(`Msg"block remove may not have an empty name")|`Block_set_->Error(`Msg"block set may not have an empty name")|`Block_dump_->Error(`Msg"block dump may not have an empty name")|`Block_info->OkNoneend|_->OkNone(* this separates the leaf and top-level certificate from the chain,
and also reverses the intermediates (to be (leaf, CA -> subCA -> subCA')
in which subCA' signed leaf *)letseparate_chain=function|[]->Error(`Msg"empty chain")|[leaf]->Ok(leaf,[])|leaf::xs->Ok(leaf,List.revxs)letwire_command_of_certcert=matchX509.Extension.(find(UnsupportedVmm_asn.oid)(X509.Certificate.extensionscert))with|None->Error`Not_present|Some(_,data)->let*v,wire=Vmm_asn.of_cert_extensiondatainifnotVmm_commands.(is_currentv)thenLogs.warn(funm->m"version mismatch, received %a current %a"Vmm_commands.pp_versionvVmm_commands.pp_versionVmm_commands.current);Ok(v,wire)letextract_policieschain=List.fold_left(funacccert->matchacc,wire_command_of_certcertwith|Errore,_->Errore|Okacc,Error`Not_present->Okacc|Ok_,Error(`Msgmsg)->Error(`Msgmsg)|Ok(prefix,acc),Ok(_,`Policy_cmd`Policy_addp)->let*name=let*cn=cert_namecertinmatchcnwith|None->Okprefix|Somex->Vmm_core.Name.append_pathprefixxinOk(name,(name,p)::acc)|_,Okwire->Error(`Msg(Fmt.str"unexpected wire %a"(Vmm_commands.pp~verbose:false)(sndwire))))(Ok(Vmm_core.Name.root_path,[]))chainlethandlechain=let*()=ifList.lengthchain<10thenOk()elseError(`Msg"certificate chain too long")inlet*leaf,rest=separate_chainchainin(* use subject common names of intermediate certs as prefix *)let*path,policies=extract_policiesrestin(* and subject common name of leaf certificate -- as name *)let*name=let*cn=cert_nameleafinmatchcnwith|None|Some"."|Some":"->Ok(Vmm_core.Name.create_of_pathpath)|Somex->Vmm_core.Name.createpathxinLogs.debug(funm->m"name is %a leaf is %a, chain %a"Vmm_core.Name.ppnameX509.Certificate.ppleafFmt.(list~sep:(any" -> ")X509.Certificate.pp)rest);matchwire_command_of_certleafwith|Error`Msgp->Error(`Msgp)|Error`Not_present->Error(`Msg"leaf certificate does not contain an albatross extension")|Ok(v,wire)->(* we only allow some commands via certificate *)matchwirewith|`Console_cmd(`Console_subscribe_)|`Console_cmd(`Old_console_subscribe_)|`Stats_cmd`Stats_subscribe|`Unikernel_cmd_|`Policy_cmd`Policy_info|`Block_cmd_->Ok(name,policies,v,wire)|_->Error(`Msg"unexpected command")