3.1.4.2.19 Receiving an EfsRpcEncryptFileExSrv Message (Opnum 21)

The EfsRpcEncryptFileExSrv method is used to convert a given object on the server to an encrypted state in the server's data store.<63>

 long EfsRpcEncryptFileExSrv(
   [in] handle_t binding_h,
   [in, string] wchar_t* FileName,
   [in, string, unique] wchar_t* ProtectorDescriptor, 
   [in] unsigned long Flags
 );

binding_h: This is an RPC binding handle parameter, as specified in [C706] and [MS-RPCE] section 2.

FileName: An EFSRPC identifier as specified in section 2.2.1.

ProtectorDescriptor: This parameter can be NULL. When it is non-NULL, it MUST contain either an RMS descriptor, which is the literal value of "EFSRMSDESC=" followed by an EnterpriseID (described below), followed by a "|" (pipe character), optionally followed by a GUID in curly braces format which, when present, is to be used as a lookup for an RMS template for the creation of a file in EFSRPC Metadata Version 3, as specified in section 2.2.2.3, or a DPAPI-NG descriptor string as described later in this section. This parameter MUST NOT contain both an RMS descriptor and a DPAPI-NG descriptor in the string.

A DPAPI-NG descriptor string is a Cryptography Next Generation DPAPI protection-descriptor rule string that contains a sequential list of one or more protectors. There MUST be at least one protector. If there is more than one, the protectors MUST be separated in the string by "AND" or "OR" string literals that MUST be capitalized. The following syntax shows the string format of a protection descriptor.

 Descriptor = [ Protector-or
               *( OR-separator Protector-or ) ]
  
     Protector-or = Protector-and
               *( AND-separator Protector-and )
  
     OR-separator = "OR"
     AND-separator = "AND"
  
     Protector-and = providerName EQUALS providerAttributes
  
     providerName = descr
  
     providerAttribute = string | hexstring
  
       ; The following characters are to be escaped when they appear
       ; in the value to be encoded: ESC, one of <escaped>, leading
       ; SHARP or SPACE, trailing SPACE, and NULL.
       string =   [ ( leadchar / pair ) [ *( stringchar / pair )
          ( trailchar / pair ) ] ]
  
       leadchar = LUTF1 / UTFMB
       LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A / %x3D / %x3F-5B / %x5D-7F
  
       trailchar  = TUTF1 / UTFMB
       TUTF1 = %x01-1F / %x21 / %x23-2A / %x2D-3A / %x3D / %x3F-5B / %x5D-7F
  
       stringchar = SUTF1 / UTFMB
       SUTF1 = %x01-21 / %x23-2A / %x2D-3A / %x3D / %x3F-5B / %x5D-7F
  
       pair = ESC ( ESC / special / hexpair )
       special = escaped / SPACE / SHARP / EQUALS
       escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
       hexstring = SHARP 1*hexpair
       hexpair = HEX HEX
  
       descr   = leadkeychar *keychar
       leadkeychar = ALPHA
       keychar = ALPHA / DIGIT / HYPHEN
       number  = DIGIT / ( LDIGIT 1*DIGIT )
  
       ALPHA   = %x41-5A / %x61-7A   ; "A"-"Z" / "a"-"z"
       DIGIT   = %x30 / LDIGIT       ; "0"-"9"
       LDIGIT  = %x31-39             ; "1"-"9"
       HEX     = DIGIT / %x41-46 / %x61-66 ; "0"-"9" / "A"-"F" / "a"-"f"
  
       NULL    = %x00 ; null (0)
       SPACE   = %x20 ; space (" ")
       DQUOTE  = %x22 ; quote (""")
       SHARP   = %x23 ; octothorpe (or sharp sign) ("#")
       DOLLAR  = %x24 ; dollar sign ("$")
       SQUOTE  = %x27 ; single quote ("'")
       LPAREN  = %x28 ; left paren ("(")
       RPAREN  = %x29 ; right paren (")")
       PLUS    = %x2B ; plus sign ("+")
       COMMA   = %x2C ; comma (",")
       HYPHEN  = %x2D ; hyphen ("-")
       DOT     = %x2E ; period (".")
       SEMI    = %x3B ; semicolon (";")
       LANGLE  = %x3C ; left angle bracket ("<")
       EQUALS  = %x3D ; equals sign ("=")
       RANGLE  = %x3E ; right angle bracket (">")
       ESC     = %x5C ; backslash ("\")
       USCORE  = %x5F ; underscore ("_")
       LCURLY  = %x7B ; left curly brace "{"
       RCURLY  = %x7D ; right curly brace "}"
  
       ; Any UTF-8 [RFC3629] encoded Unicode [Unicode] character
       UTF8    = UTF1 / UTFMB
       UTFMB   = UTF2 / UTF3 / UTF4
       UTF0    = %x80-BF
       UTF1    = %x00-7F
       UTF2    = %xC2-DF UTF0
       UTF3    = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) /
                 %xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
       UTF4    = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) /
                 %xF4 %x80-8F 2(UTF0)
  
       OCTET   = %x00-FF ; Any octet (8-bit data unit)

A DPAPI-NG descriptor SHOULD have a providerName of "LOCKEDCREDENTIALS" or "VAULTCREDENTIALS", and providerAttributes SHOULD BE formatted as follows:

 providerAttributes = MS-ENTID:[CallerIDString] "|" SessionIDString  ["|"UserSidString],EnterpriseID

When providerAttributes is specified as above, if CallerIDString is present, it MUST be a string defined by the endpoint for key lookup; it MUST work only on that endpoint and only when used in conjunction with the matching UserSidString; SessionIDString MUST be a GUID, and when UserSidString is present, it MUST be the SID (as specified in [MS-DTYP] section 2.4.2.3) of the user who owns the key. EnterpriseID MUST be an Internet domain name that is not a top-level domain, as described in [RFC1035].

Flags: This parameter is unused and MUST be ignored by the server. It MUST be set to zero by the client.

Return Values: The server MUST return 0 if it successfully processes the message received from the client. The server MUST return a nonzero value if processing fails.

If ProtectorDescriptor is NULL, follow the processing rules for EfsRpcEncryptFileSrv, using the values of binding_h and FileName.

Otherwise, if no object exists on the server with the specified name, the server MUST return a nonzero value. If the object exists and is already encrypted:

  • If the object is a container for other objects, the server SHOULD return 0 to indicate success.

  • If the object is not a container object, the server SHOULD check to confirm that the calling user has access to a private key that can decrypt the file and, if so, return 0 to indicate success. If the calling user does not have access to a private key that can decrypt the file, the server SHOULD return a nonzero value.

If the object exists and is not encrypted, the server SHOULD use the RMS template to create a user Rights Management Services (RMS) Publishing License (PL) for the user, as specified in [MS-RMPR] section 2.2.9.7, certificate for the calling user, specifying the client identity associated with the RPC call ([MS-RPCE] section 3.3.3.4.3) as input for the security context. If an error is returned when looking up the template or creating a PL, the server MUST return a nonzero value.

The server then performs the following actions to convert the object to an encrypted state in its data store:

  • If the data object referred to by FileName exists on the server and is a container for other objects, the server MUST set an attribute on the container that instructs the data store to encrypt any new objects created in that container using a key associated with the ProtectorDescriptor. The server MAY encrypt unencrypted objects that were already in the container before this message was received.

  • Otherwise, the server SHOULD:

    • Randomly generate a File Encryption Key (FEK) for the object and use it to encrypt the object.

    • If the ProtectorDescriptor is a DPAPI-NG protector, create EFSRPC Metadata Version 2 for the object, formatted as specified in section 2.2.2.2. The Data Decryption Field SHOULD contain a single entry corresponding to a DPAPI-NG protector as mentioned previously.

    • If the ProtectorDescriptor is an RMS protector, create EFSRPC Metadata Version 3 for the object, formatted as specified in section 2.2.2.3.

  • Return 0 to indicate success.

Upon completion of this request, the converted object MUST be accessible to the calling user for read and write methods of the storage encryption system.