code: @Override
      protected void DecodeFromCBORObject(CBORObject obj) throws CoseException {
          if (obj.size() != 4) throw new CoseException("Invalid SignMessage structure");
          
          if (obj.get(0).getType() == CBORType.ByteString) {
              rgbProtected = obj.get(0).GetByteString();
              if (obj.get(0).GetByteString().length == 0) {
                  objProtected = CBORObject.NewMap();
              }
              else {
                  objProtected = CBORObject.DecodeFromBytes(rgbProtected);
                  if (objProtected.size() == 0) rgbProtected = new byte[0];
              }
          }
          else throw new CoseException("Invalid SignMessage structure");
          
          if (obj.get(1).getType() == CBORType.Map) {
              objUnprotected = obj.get(1);
          }
          else throw new CoseException("Invalid SignMessage structure");
          
          if (obj.get(2).getType() == CBORType.ByteString) rgbContent = obj.get(2).GetByteString();
          else if (!obj.get(2).isNull()) throw new CoseException("Invalid SignMessage structure");
          
          if (obj.get(3).getType() == CBORType.Array) {
              for (int i=0; i<obj.get(3).size(); i++) {
                  Signer signer = new Signer();
                  signer.DecodeFromCBORObject(obj.get(3).get(i));
                  signerList.add(signer);
              }
          }
          else throw new CoseException("Invalid SignMessage structure");
      }
docs: Internal function used in creating a SignMessage object from a byte string.
  
  @param obj COSE_Sign encoded object.
  @throws CoseException Errors generated by the COSE module