gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/pkcs11_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2021 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package builtin_test
    21  
    22  import (
    23  	. "gopkg.in/check.v1"
    24  
    25  	"gitee.com/mysnapcore/mysnapd/interfaces"
    26  	"gitee.com/mysnapcore/mysnapd/interfaces/apparmor"
    27  	"gitee.com/mysnapcore/mysnapd/interfaces/builtin"
    28  	"gitee.com/mysnapcore/mysnapd/interfaces/seccomp"
    29  	"gitee.com/mysnapcore/mysnapd/snap"
    30  	"gitee.com/mysnapcore/mysnapd/snap/snaptest"
    31  	"gitee.com/mysnapcore/mysnapd/testutil"
    32  )
    33  
    34  type Pkcs11InterfaceSuite struct {
    35  	testutil.BaseTest
    36  
    37  	iface            interfaces.Interface
    38  	testSlot0Info    *snap.SlotInfo
    39  	testSlot0        *interfaces.ConnectedSlot
    40  	testSlot1Info    *snap.SlotInfo
    41  	testSlot1        *interfaces.ConnectedSlot
    42  	testSlot2Info    *snap.SlotInfo
    43  	testSlot2        *interfaces.ConnectedSlot
    44  	testSlot3Info    *snap.SlotInfo
    45  	testSlot3        *interfaces.ConnectedSlot
    46  	testSlot4Info    *snap.SlotInfo
    47  	testSlot4        *interfaces.ConnectedSlot
    48  	testBadSlot0Info *snap.SlotInfo
    49  	testBadSlot0     *interfaces.ConnectedSlot
    50  	testBadSlot1Info *snap.SlotInfo
    51  	testBadSlot1     *interfaces.ConnectedSlot
    52  	testBadSlot2Info *snap.SlotInfo
    53  	testBadSlot2     *interfaces.ConnectedSlot
    54  	testBadSlot3Info *snap.SlotInfo
    55  	testBadSlot3     *interfaces.ConnectedSlot
    56  	testBadSlot4Info *snap.SlotInfo
    57  	testBadSlot4     *interfaces.ConnectedSlot
    58  	testBadSlot5Info *snap.SlotInfo
    59  	testBadSlot5     *interfaces.ConnectedSlot
    60  	testBadSlot6Info *snap.SlotInfo
    61  	testBadSlot6     *interfaces.ConnectedSlot
    62  
    63  	testPlug0Info *snap.PlugInfo
    64  	testPlug0     *interfaces.ConnectedPlug
    65  	testPlug1Info *snap.PlugInfo
    66  	testPlug1     *interfaces.ConnectedPlug
    67  	testPlug2Info *snap.PlugInfo
    68  	testPlug2     *interfaces.ConnectedPlug
    69  }
    70  
    71  var _ = Suite(&Pkcs11InterfaceSuite{
    72  	iface: builtin.MustInterface("pkcs11"),
    73  })
    74  
    75  func (s *Pkcs11InterfaceSuite) SetUpTest(c *C) {
    76  	s.BaseTest.SetUpTest(c)
    77  
    78  	gadgetSnapInfo := snaptest.MockInfo(c, `name: gadget
    79  version: 0
    80  type: gadget
    81  slots:
    82    pkcs11-optee-slot-0:
    83      interface: pkcs11
    84      pkcs11-socket: /run/p11-kit/pkcs11-optee-slot-0
    85    pkcs11-optee-slot-1:
    86      interface: pkcs11
    87      pkcs11-socket: /run/p11-kit/pkcs11-optee-slot-1
    88    pkcs11-optee-slot-2:
    89      interface: pkcs11
    90      pkcs11-socket: /run/p11-kit/pkcs11-optee-slot-2
    91    pkcs11-optee-slot-3:
    92      interface: pkcs11
    93      pkcs11-socket: /run/p11-kit/optee-slot-3
    94    pkcs11-atec-slot-1:
    95      interface: pkcs11
    96      pkcs11-socket: /run/p11-kit/atec-608-slot-1
    97    pkcs11-bad-optee-slot-0:
    98      interface: pkcs11
    99      pkcs11-socket: /run/p12-kit/pkcs11-optee-slot-0
   100    pkcs11-bad-optee-slot-1:
   101      interface: pkcs11
   102      pkcs11-socket: 22
   103    pkcs11-bad-optee-slot-2:
   104      interface: pkcs11
   105      pkcs11-socket: /run/p11-kit/pkcs11-optee-slot-*
   106    pkcs11-bad-optee-slot-3:
   107      interface: pkcs11
   108      pkcs11-socket: /run/p11-kit/../pkcs11-optee-slot-0
   109    pkcs11-bad-optee-slot-4:
   110      interface: pkcs11
   111    pkcs11-bad-optee-slot-5:
   112      interface: pkcs11
   113      pkcs11-socket: /run/p11-kit/p11/pkcs11-optee-slot-0
   114    pkcs11-bad-optee-slot-6:
   115      interface: pkcs11
   116      pkcs11-socket: ../run/p11-kit/pkcs11-optee-slot-0
   117  
   118  apps:
   119    p11-server:
   120      slots:
   121        - pkcs11-optee-slot-0
   122        - pkcs11-optee-slot-1
   123  `, nil)
   124  	s.testSlot0Info = gadgetSnapInfo.Slots["pkcs11-optee-slot-0"]
   125  	s.testSlot0 = interfaces.NewConnectedSlot(s.testSlot0Info, nil, nil)
   126  	s.testSlot1Info = gadgetSnapInfo.Slots["pkcs11-optee-slot-1"]
   127  	s.testSlot1 = interfaces.NewConnectedSlot(s.testSlot1Info, nil, nil)
   128  	s.testSlot2Info = gadgetSnapInfo.Slots["pkcs11-optee-slot-2"]
   129  	s.testSlot2 = interfaces.NewConnectedSlot(s.testSlot2Info, nil, nil)
   130  	s.testSlot3Info = gadgetSnapInfo.Slots["pkcs11-optee-slot-3"]
   131  	s.testSlot3 = interfaces.NewConnectedSlot(s.testSlot3Info, nil, nil)
   132  	s.testSlot4Info = gadgetSnapInfo.Slots["pkcs11-atec-slot-1"]
   133  	s.testSlot4 = interfaces.NewConnectedSlot(s.testSlot4Info, nil, nil)
   134  	s.testBadSlot0Info = gadgetSnapInfo.Slots["pkcs11-bad-optee-slot-0"]
   135  	s.testBadSlot0 = interfaces.NewConnectedSlot(s.testBadSlot0Info, nil, nil)
   136  	s.testBadSlot1Info = gadgetSnapInfo.Slots["pkcs11-bad-optee-slot-1"]
   137  	s.testBadSlot1 = interfaces.NewConnectedSlot(s.testBadSlot1Info, nil, nil)
   138  	s.testBadSlot2Info = gadgetSnapInfo.Slots["pkcs11-bad-optee-slot-2"]
   139  	s.testBadSlot2 = interfaces.NewConnectedSlot(s.testBadSlot2Info, nil, nil)
   140  	s.testBadSlot3Info = gadgetSnapInfo.Slots["pkcs11-bad-optee-slot-3"]
   141  	s.testBadSlot3 = interfaces.NewConnectedSlot(s.testBadSlot3Info, nil, nil)
   142  	s.testBadSlot4Info = gadgetSnapInfo.Slots["pkcs11-bad-optee-slot-4"]
   143  	s.testBadSlot4 = interfaces.NewConnectedSlot(s.testBadSlot4Info, nil, nil)
   144  	s.testBadSlot5Info = gadgetSnapInfo.Slots["pkcs11-bad-optee-slot-5"]
   145  	s.testBadSlot5 = interfaces.NewConnectedSlot(s.testBadSlot5Info, nil, nil)
   146  	s.testBadSlot6Info = gadgetSnapInfo.Slots["pkcs11-bad-optee-slot-6"]
   147  	s.testBadSlot6 = interfaces.NewConnectedSlot(s.testBadSlot6Info, nil, nil)
   148  
   149  	consumingSnapInfo := snaptest.MockInfo(c, `name: consumer
   150  version: 0
   151  plugs:
   152    plug-for-socket-0:
   153      interface: pkcs11
   154    plug-for-socket-1:
   155      interface: pkcs11
   156    plug-for-socket-2:
   157      interface: pkcs11
   158  
   159  apps:
   160    app-accessing-1-slot:
   161      command: foo
   162      plugs: [plug-for-socket-0]
   163    app-accessing-2-slots:
   164      command: bar
   165      plugs: [plug-for-socket-0, plug-for-socket-1]
   166    app-accessing-3rd-slot:
   167      command: foo
   168      plugs: [plug-for-socket-2]
   169  `, nil)
   170  	s.testPlug0Info = consumingSnapInfo.Plugs["plug-for-socket-0"]
   171  	s.testPlug0 = interfaces.NewConnectedPlug(s.testPlug0Info, nil, nil)
   172  	s.testPlug1Info = consumingSnapInfo.Plugs["plug-for-socket-1"]
   173  	s.testPlug1 = interfaces.NewConnectedPlug(s.testPlug1Info, nil, nil)
   174  	s.testPlug2Info = consumingSnapInfo.Plugs["plug-for-socket-2"]
   175  	s.testPlug2 = interfaces.NewConnectedPlug(s.testPlug2Info, nil, nil)
   176  }
   177  
   178  func (s *Pkcs11InterfaceSuite) TestName(c *C) {
   179  	c.Assert(s.iface.Name(), Equals, "pkcs11")
   180  }
   181  
   182  func (s *Pkcs11InterfaceSuite) TestSecCompPermanentSlot(c *C) {
   183  	seccompSpec := &seccomp.Specification{}
   184  	err := seccompSpec.AddPermanentSlot(s.iface, s.testSlot0Info)
   185  	c.Assert(err, IsNil)
   186  	c.Assert(seccompSpec.SecurityTags(), DeepEquals, []string{"snap.gadget.p11-server"})
   187  	c.Check(seccompSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains, "listen\n")
   188  }
   189  
   190  func (s *Pkcs11InterfaceSuite) TestPermanentSlotSnippetAppArmor(c *C) {
   191  	apparmorSpec := &apparmor.Specification{}
   192  
   193  	err := apparmorSpec.AddPermanentSlot(s.iface, s.testSlot0Info)
   194  	c.Assert(err, IsNil)
   195  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.gadget.p11-server"})
   196  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), Not(IsNil))
   197  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   198  		`# pkcs11 socket dir`)
   199  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   200  		`/{,var/}run/p11-kit/  rw,`)
   201  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   202  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-0" rwk,`)
   203  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   204  		`# pkcs11 config`)
   205  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   206  		`/etc/pkcs11/{,**} r,`)
   207  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   208  		`/usr/bin/p11-kit ixr,`)
   209  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   210  		`/usr/bin/p11tool ixr,`)
   211  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   212  		`/usr/bin/pkcs11-tool ixr,`)
   213  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   214  		`/usr/libexec/p11-kit/p11-kit-server ixr,`)
   215  	err = apparmorSpec.AddPermanentSlot(s.iface, s.testSlot1Info)
   216  	c.Assert(err, IsNil)
   217  	c.Assert(apparmorSpec.SnippetForTag("snap.gadget.p11-server"), testutil.Contains,
   218  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-1" rwk,`)
   219  }
   220  
   221  func (s *Pkcs11InterfaceSuite) TestPermanentSlotMissingSocketPath(c *C) {
   222  	apparmorSpec := &apparmor.Specification{}
   223  
   224  	c.Assert(apparmorSpec.AddPermanentSlot(s.iface, s.testBadSlot4Info), ErrorMatches, `cannot use pkcs11 slot without "pkcs11-socket" attribute`)
   225  }
   226  
   227  func (s *Pkcs11InterfaceSuite) TestConnectedPlugSnippetAppArmor(c *C) {
   228  	apparmorSpec := &apparmor.Specification{}
   229  
   230  	err := apparmorSpec.AddConnectedPlug(s.iface, s.testPlug1, s.testSlot1)
   231  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.consumer.app-accessing-2-slots"})
   232  	c.Assert(err, IsNil)
   233  	err = apparmorSpec.AddConnectedPlug(s.iface, s.testPlug0, s.testSlot0)
   234  	c.Assert(err, IsNil)
   235  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.consumer.app-accessing-1-slot", "snap.consumer.app-accessing-2-slots"})
   236  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), Not(IsNil))
   237  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   238  		`# pkcs11 config for p11-proxy`)
   239  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   240  		`/etc/pkcs11/{,**} r,`)
   241  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   242  		`# pkcs11 tools`)
   243  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   244  		`/usr/bin/p11tool ixr,`)
   245  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   246  		`/usr/bin/pkcs11-tool ixr,`)
   247  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   248  		`/usr/share/p11-kit/modules/ r,`)
   249  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   250  		`/usr/share/p11-kit/modules/* r,`)
   251  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), testutil.Contains,
   252  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-0" rw,`)
   253  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), Not(testutil.Contains),
   254  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-1" rw,`)
   255  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-1-slot"), Not(testutil.Contains),
   256  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-2" rw,`)
   257  
   258  	c.Assert(err, IsNil)
   259  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-2-slots"), testutil.Contains,
   260  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-0" rw,`)
   261  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-2-slots"), testutil.Contains,
   262  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-1" rw,`)
   263  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-2-slots"), Not(testutil.Contains),
   264  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-2" rw,`)
   265  
   266  	err = apparmorSpec.AddConnectedPlug(s.iface, s.testPlug2, s.testSlot2)
   267  	c.Assert(err, IsNil)
   268  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.consumer.app-accessing-1-slot", "snap.consumer.app-accessing-2-slots", "snap.consumer.app-accessing-3rd-slot"})
   269  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-3rd-slot"), Not(testutil.Contains),
   270  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-0" rw,`)
   271  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-3rd-slot"), Not(testutil.Contains),
   272  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-1" rw,`)
   273  	c.Assert(apparmorSpec.SnippetForTag("snap.consumer.app-accessing-3rd-slot"), testutil.Contains,
   274  		`"/{,var/}run/p11-kit/pkcs11-optee-slot-2" rw,`)
   275  
   276  	err = apparmorSpec.AddConnectedPlug(s.iface, s.testPlug2, s.testBadSlot4)
   277  	c.Assert(err, ErrorMatches, `internal error: pkcs11 slot "gadget:.*" must have a unix socket "pkcs11-socket" attribute`)
   278  }
   279  
   280  func (s *Pkcs11InterfaceSuite) TestSanitizeGadgetSnapSlots(c *C) {
   281  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testSlot0Info), IsNil)
   282  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testSlot1Info), IsNil)
   283  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testSlot2Info), IsNil)
   284  }
   285  
   286  func (s *Pkcs11InterfaceSuite) TestSanitizeBadGadgetSnapSlots(c *C) {
   287  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testSlot1Info), IsNil)
   288  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testSlot2Info), IsNil)
   289  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testSlot3Info), IsNil)
   290  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testSlot4Info), IsNil)
   291  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testBadSlot0Info), ErrorMatches, `pkcs11 unix socket has to be in the /run/p11-kit directory: "/run/p12.*"`)
   292  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testBadSlot1Info), ErrorMatches, `pkcs11 slot "pkcs11-socket" attribute must be a string, not 22`)
   293  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testBadSlot2Info), ErrorMatches, `pkcs11 unix socket path is invalid: "/run/p11-kit/pkcs11-optee-slot-\*" contains a reserved apparmor char .*`)
   294  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testBadSlot3Info), ErrorMatches, `pkcs11 unix socket path is not clean: ".*"`)
   295  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testBadSlot4Info), ErrorMatches, `cannot use pkcs11 slot without "pkcs11-socket" attribute`)
   296  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testBadSlot5Info), ErrorMatches, `pkcs11 unix socket has to be in the /run/p11-kit directory: "/run/p11-kit/p11/.*"`)
   297  	c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testBadSlot6Info), ErrorMatches, `pkcs11 unix socket path is not clean: "\.\./.*"`)
   298  }
   299  
   300  func (s *Pkcs11InterfaceSuite) TestStaticInfo(c *C) {
   301  	si := interfaces.StaticInfoOf(s.iface)
   302  	c.Check(si.ImplicitOnCore, Equals, false)
   303  	c.Check(si.ImplicitOnClassic, Equals, false)
   304  	c.Check(si.Summary, Equals, `allows use of pkcs11 framework and access to exposed tokens`)
   305  	c.Check(si.BaseDeclarationSlots, testutil.Contains, "pkcs11")
   306  }
   307  
   308  func (s *Pkcs11InterfaceSuite) TestAutoConnect(c *C) {
   309  	c.Assert(s.iface.AutoConnect(s.testPlug0Info, s.testSlot1Info), Equals, true)
   310  }
   311  
   312  func (s *Pkcs11InterfaceSuite) TestInterfaces(c *C) {
   313  	c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface)
   314  }