LCOV - code coverage report
Current view: top level - dom/webauthn - WebAuthnUtil.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 49 2.0 %
Date: 2017-07-14 16:53:18 Functions: 2 5 40.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/dom/WebAuthnUtil.h"
       8             : #include "pkixutil.h"
       9             : 
      10             : namespace mozilla {
      11             : namespace dom {
      12             : 
      13             : nsresult
      14           0 : ReadToCryptoBuffer(pkix::Reader& aSrc, /* out */ CryptoBuffer& aDest,
      15             :                    uint32_t aLen)
      16             : {
      17           0 :   if (aSrc.EnsureLength(aLen) != pkix::Success) {
      18           0 :     return NS_ERROR_DOM_UNKNOWN_ERR;
      19             :   }
      20             : 
      21           0 :   aDest.ClearAndRetainStorage();
      22             : 
      23           0 :   for (uint32_t offset = 0; offset < aLen; ++offset) {
      24             :     uint8_t b;
      25           0 :     if (aSrc.Read(b) != pkix::Success) {
      26           0 :       return NS_ERROR_DOM_UNKNOWN_ERR;
      27             :     }
      28           0 :     if (!aDest.AppendElement(b, mozilla::fallible)) {
      29           0 :       return NS_ERROR_OUT_OF_MEMORY;
      30             :     }
      31             :   }
      32             : 
      33           0 :   return NS_OK;
      34             : }
      35             : 
      36             : nsresult
      37           0 : U2FAssembleAuthenticatorData(/* out */ CryptoBuffer& aAuthenticatorData,
      38             :                              const CryptoBuffer& aRpIdHash,
      39             :                              const CryptoBuffer& aSignatureData)
      40             : {
      41             :   // The AuthenticatorData for U2F devices is the concatenation of the
      42             :   // RP ID with the output of the U2F Sign operation.
      43           0 :   if (aRpIdHash.Length() != 32) {
      44           0 :     return NS_ERROR_INVALID_ARG;
      45             :   }
      46             : 
      47           0 :   if (!aAuthenticatorData.AppendElements(aRpIdHash, mozilla::fallible)) {
      48           0 :     return NS_ERROR_OUT_OF_MEMORY;
      49             :   }
      50             : 
      51           0 :   if (!aAuthenticatorData.AppendElements(aSignatureData, mozilla::fallible)) {
      52           0 :     return NS_ERROR_OUT_OF_MEMORY;
      53             :   }
      54             : 
      55           0 :   return NS_OK;
      56             : }
      57             : 
      58             : nsresult
      59           0 : U2FDecomposeRegistrationResponse(const CryptoBuffer& aResponse,
      60             :                                  /* out */ CryptoBuffer& aPubKeyBuf,
      61             :                                  /* out */ CryptoBuffer& aKeyHandleBuf,
      62             :                                  /* out */ CryptoBuffer& aAttestationCertBuf,
      63             :                                  /* out */ CryptoBuffer& aSignatureBuf)
      64             : {
      65             :   // U2F v1.1 Format via
      66             :   // http://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html
      67             :   //
      68             :   // Bytes  Value
      69             :   // 1      0x05
      70             :   // 65     public key
      71             :   // 1      key handle length
      72             :   // *      key handle
      73             :   // ASN.1  attestation certificate
      74             :   // *      attestation signature
      75             : 
      76           0 :   pkix::Input u2fResponse;
      77           0 :   u2fResponse.Init(aResponse.Elements(), aResponse.Length());
      78             : 
      79           0 :   pkix::Reader input(u2fResponse);
      80             : 
      81             :   uint8_t b;
      82           0 :   if (input.Read(b) != pkix::Success) {
      83           0 :     return NS_ERROR_DOM_UNKNOWN_ERR;
      84             :   }
      85           0 :   if (b != 0x05) {
      86           0 :     return NS_ERROR_DOM_UNKNOWN_ERR;
      87             :   }
      88             : 
      89           0 :   nsresult rv = ReadToCryptoBuffer(input, aPubKeyBuf, 65);
      90           0 :   if (NS_FAILED(rv)) {
      91           0 :     return rv;
      92             :   }
      93             : 
      94             :   uint8_t handleLen;
      95           0 :   if (input.Read(handleLen) != pkix::Success) {
      96           0 :     return NS_ERROR_DOM_UNKNOWN_ERR;
      97             :   }
      98             : 
      99           0 :   rv = ReadToCryptoBuffer(input, aKeyHandleBuf, handleLen);
     100           0 :   if (NS_FAILED(rv)) {
     101           0 :     return rv;
     102             :   }
     103             : 
     104             :   // We have to parse the ASN.1 SEQUENCE on the outside to determine the cert's
     105             :   // length.
     106           0 :   pkix::Input cert;
     107           0 :   if (pkix::der::ExpectTagAndGetValue(input, pkix::der::SEQUENCE, cert)
     108             :       != pkix::Success) {
     109           0 :     return NS_ERROR_DOM_UNKNOWN_ERR;
     110             :   }
     111             : 
     112           0 :   pkix::Reader certInput(cert);
     113           0 :   rv = ReadToCryptoBuffer(certInput, aAttestationCertBuf, cert.GetLength());
     114           0 :   if (NS_FAILED(rv)) {
     115           0 :     return rv;
     116             :   }
     117             : 
     118             :   // The remainder of u2fResponse is the signature
     119           0 :   pkix::Input u2fSig;
     120           0 :   input.SkipToEnd(u2fSig);
     121           0 :   pkix::Reader sigInput(u2fSig);
     122           0 :   rv = ReadToCryptoBuffer(sigInput, aSignatureBuf, u2fSig.GetLength());
     123           0 :   if (NS_FAILED(rv)) {
     124           0 :     return rv;
     125             :   }
     126             : 
     127           0 :   return NS_OK;
     128             : }
     129             : 
     130             : }
     131           9 : }

Generated by: LCOV version 1.13