LCOV - code coverage report
Current view: top level - src/edhoc - retrieve_cred.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 37 70 52.9 %
Date: 2024-09-16 20:15:30 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 21 67 31.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
       3                 :            :    file at the top-level directory of this distribution.
       4                 :            : 
       5                 :            :    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
       6                 :            :    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
       7                 :            :    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
       8                 :            :    option. This file may not be copied, modified, or distributed
       9                 :            :    except according to those terms.
      10                 :            : */
      11                 :            : 
      12                 :            : #include <string.h>
      13                 :            : 
      14                 :            : #include "edhoc/cert.h"
      15                 :            : #include "edhoc/bstr_encode_decode.h"
      16                 :            : #include "edhoc/retrieve_cred.h"
      17                 :            : 
      18                 :            : #include "common/crypto_wrapper.h"
      19                 :            : #include "common/oscore_edhoc_error.h"
      20                 :            : #include "common/print_util.h"
      21                 :            : #include "common/memcpy_s.h"
      22                 :            : 
      23                 :            : #include "cbor/edhoc_decode_id_cred_x.h"
      24                 :            : 
      25                 :            : /**
      26                 :            :  * @brief                       Verifies a certificate and copies it to the cred 
      27                 :            :  *                              buffer. It also extracts the public key
      28                 :            :  *                              contained in the certificate. 
      29                 :            :  * 
      30                 :            :  * @param static_dh_auth        Type of the key contained in the certificate -- 
      31                 :            :  *                              signature key or static DH key.
      32                 :            :  * @param cred_array            array containing credentials.
      33                 :            :  * @param label                 CBOR map label of id_cred_x.
      34                 :            :  * @param[in] cert              The certificate.
      35                 :            :  * @param[in] cred              Cred buffer.
      36                 :            :  * @param[in] pk                Public key.
      37                 :            :  * @param[in] g                 Static DH public key.
      38                 :            :  * @return                      Ok or error code
      39                 :            :  */
      40                 :            : static inline enum err
      41                 :          2 : verify_cert2cred(bool static_dh_auth, struct cred_array *cred_array,
      42                 :            :                  enum id_cred_x_label label, struct const_byte_array *cert,
      43                 :            :                  struct byte_array *cred, struct byte_array *pk,
      44                 :            :                  struct byte_array *g)
      45                 :            : {
      46                 :          2 :         PRINT_ARRAY("ID_CRED_x contains a certificate", cert->ptr, cert->len);
      47         [ -  + ]:          2 :         TRY(encode_bstr((struct byte_array *)cert, cred));
      48                 :            : 
      49                 :          2 :         bool verified = false;
      50      [ +  -  - ]:          2 :         switch (label) {
      51                 :            :         /* for now we transfer a single certificate, therefore bag and chain are the same */
      52                 :          2 :         case x5bag:
      53                 :            :         case x5chain:
      54         [ -  + ]:          2 :                 if (static_dh_auth) {
      55                 :          0 :                         pk->len = 0;
      56         [ #  # ]:          0 :                         TRY(cert_x509_verify(cert, cred_array, g, &verified));
      57                 :            :                 } else {
      58                 :          2 :                         g->len = 0;
      59         [ -  + ]:          2 :                         TRY(cert_x509_verify(cert, cred_array, pk, &verified));
      60                 :            :                 }
      61                 :          2 :                 break;
      62                 :          0 :         case c5b:
      63                 :            :         case c5c:
      64         [ #  # ]:          0 :                 if (static_dh_auth) {
      65                 :          0 :                         pk->len = 0;
      66         [ #  # ]:          0 :                         TRY(cert_c509_verify(cert, cred_array, g, &verified));
      67                 :            :                 } else {
      68                 :          0 :                         g->len = 0;
      69         [ #  # ]:          0 :                         TRY(cert_c509_verify(cert, cred_array, pk, &verified));
      70                 :            :                 }
      71                 :          0 :                 break;
      72                 :            :                 break;
      73                 :            : 
      74                 :          0 :         default:
      75                 :          0 :                 break;
      76                 :            :         }
      77                 :            : 
      78         [ +  - ]:          2 :         if (verified) {
      79                 :          2 :                 PRINT_MSG("Certificate verification successful!\n");
      80                 :          2 :                 return ok;
      81                 :            :         } else {
      82                 :          0 :                 return certificate_authentication_failed;
      83                 :            :         }
      84                 :            :         return ok;
      85                 :            : }
      86                 :            : 
      87                 :            : /**
      88                 :            :  * @brief                       Get the local cred object.
      89                 :            :  * 
      90                 :            :  * @param static_dh_auth        True if static DH is used for authentication.
      91                 :            :  * @param[in] cred_array        An array of trust anchors
      92                 :            :  * @param[in] ID_cred           The ID of the actual credential.
      93                 :            :  * @param[out] cred             The retrievd credentials        
      94                 :            :  * @param[out] pk               The retrievd signature authentication public key
      95                 :            :  * @param[out] g                The retrievd static DH authentication public key
      96                 :            :  * @return                      Ok or error code
      97                 :            :  */
      98                 :          4 : static enum err get_local_cred(bool static_dh_auth,
      99                 :            :                                struct cred_array *cred_array,
     100                 :            :                                struct byte_array *ID_cred,
     101                 :            :                                struct byte_array *cred, struct byte_array *pk,
     102                 :            :                                struct byte_array *g)
     103                 :            : {
     104         [ +  - ]:          4 :         for (uint32_t i = 0; i < cred_array->len; i++) {
     105         [ +  - ]:          4 :                 if ((cred_array->ptr[i].id_cred.len == ID_cred->len) &&
     106         [ +  - ]:          4 :                     (0 == memcmp(cred_array->ptr[i].id_cred.ptr, ID_cred->ptr,
     107                 :            :                                  ID_cred->len))) {
     108                 :            :                         /*retrieve CRED_x*/
     109         [ -  + ]:          4 :                         TRY(_memcpy_s(cred->ptr, cred->len,
     110                 :            :                                       cred_array->ptr[i].cred.ptr,
     111                 :            :                                       cred_array->ptr[i].cred.len));
     112                 :          4 :                         cred->len = cred_array->ptr[i].cred.len;
     113                 :            : 
     114                 :            :                         /*retrieve PK*/
     115         [ -  + ]:          4 :                         if (static_dh_auth) {
     116                 :          0 :                                 pk->len = 0;
     117         [ #  # ]:          0 :                                 if (cred_array->ptr[i].g.len == 65) {
     118                 :            :                                         /*decompressed P256 DH pk*/
     119                 :          0 :                                         g->ptr[0] = 0x2;
     120         [ #  # ]:          0 :                                         TRY(_memcpy_s(
     121                 :            :                                                 &g->ptr[1], g->len - 1,
     122                 :            :                                                 &cred_array->ptr[i].g.ptr[1],
     123                 :            :                                                 32));
     124                 :          0 :                                         g->len = 33;
     125                 :            : 
     126                 :            :                                 } else {
     127         [ #  # ]:          0 :                                         TRY(_memcpy_s(g->ptr, g->len,
     128                 :            :                                                       cred_array->ptr[i].g.ptr,
     129                 :            :                                                       cred_array->ptr[i].g.len));
     130                 :          0 :                                         g->len = cred_array->ptr[i].g.len;
     131                 :            :                                 }
     132                 :            : 
     133                 :            :                         } else {
     134                 :          4 :                                 g->len = 0;
     135         [ -  + ]:          4 :                                 TRY(_memcpy_s(pk->ptr, pk->len,
     136                 :            :                                               cred_array->ptr[i].pk.ptr,
     137                 :            :                                               cred_array->ptr[i].pk.len));
     138                 :          4 :                                 pk->len = cred_array->ptr[i].pk.len;
     139                 :            :                         }
     140                 :          4 :                         return ok;
     141                 :            :                 }
     142                 :            :         }
     143                 :            : 
     144                 :          0 :         return credential_not_found;
     145                 :            : }
     146                 :            : 
     147                 :          6 : enum err retrieve_cred(bool static_dh_auth, struct cred_array *cred_array,
     148                 :            :                        struct byte_array *id_cred, struct byte_array *cred,
     149                 :            :                        struct byte_array *pk, struct byte_array *g)
     150                 :            : {
     151                 :          6 :         size_t decode_len = 0;
     152                 :          6 :         struct id_cred_x_map map = { 0 };
     153                 :            : 
     154         [ -  + ]:          6 :         TRY_EXPECT(cbor_decode_id_cred_x_map(id_cred->ptr, id_cred->len, &map,
     155                 :            :                                              &decode_len),
     156                 :            :                    0);
     157                 :            :         /*the cred should be locally available on the device if 
     158                 :            :         kid, x5u, x5t, c5u, c5t is used*/
     159   [ +  -  +  - ]:          6 :         if (map.id_cred_x_map_kid_present || map.id_cred_x_map_x5u_present ||
     160   [ +  +  +  - ]:          6 :             map.id_cred_x_map_x5t_present || map.id_cred_x_map_c5u_present ||
     161         [ -  + ]:          2 :             map.id_cred_x_map_c5t_present) {
     162         [ -  + ]:          4 :                 TRY(get_local_cred(static_dh_auth, cred_array, id_cred, cred,
     163                 :            :                                    pk, g));
     164                 :          4 :                 return ok;
     165                 :            :         }
     166                 :            :         /*x5chain*/
     167         [ +  - ]:          2 :         else if (map.id_cred_x_map_x5chain_present) {
     168                 :          2 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     169                 :            :                         map.id_cred_x_map_x5chain.id_cred_x_map_x5chain.value,
     170                 :            :                         (uint32_t)map.id_cred_x_map_x5chain
     171                 :            :                                 .id_cred_x_map_x5chain.len);
     172                 :            : 
     173         [ -  + ]:          2 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, x5chain, &cert,
     174                 :            :                                      cred, pk, g));
     175                 :          2 :                 return ok;
     176                 :            :         }
     177                 :            :         /*x5bag*/
     178         [ #  # ]:          0 :         else if (map.id_cred_x_map_x5bag_present) {
     179                 :          0 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     180                 :            :                         map.id_cred_x_map_x5bag.id_cred_x_map_x5bag.value,
     181                 :            :                         (uint32_t)map.id_cred_x_map_x5bag.id_cred_x_map_x5bag
     182                 :            :                                 .len);
     183         [ #  # ]:          0 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, x5bag, &cert,
     184                 :            :                                      cred, pk, g));
     185                 :          0 :                 return ok;
     186                 :            :         }
     187                 :            :         /*c5c*/
     188         [ #  # ]:          0 :         else if (map.id_cred_x_map_c5c_present) {
     189                 :          0 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     190                 :            :                         map.id_cred_x_map_c5c.id_cred_x_map_c5c.value,
     191                 :            :                         (uint32_t)map.id_cred_x_map_c5c.id_cred_x_map_c5c.len);
     192         [ #  # ]:          0 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, c5c, &cert,
     193                 :            :                                      cred, pk, g));
     194                 :          0 :                 return ok;
     195                 :            :         }
     196                 :            :         /*c5b*/
     197         [ #  # ]:          0 :         else if (map.id_cred_x_map_c5b_present) {
     198                 :          0 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     199                 :            :                         map.id_cred_x_map_c5b.id_cred_x_map_c5b.value,
     200                 :            :                         (uint32_t)map.id_cred_x_map_c5b.id_cred_x_map_c5b.len);
     201         [ #  # ]:          0 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, c5b, &cert,
     202                 :            :                                      cred, pk, g));
     203                 :          0 :                 return ok;
     204                 :            :         }
     205                 :            : 
     206                 :          0 :         return credential_not_found;
     207                 :            : }

Generated by: LCOV version 1.14