⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 efibis_authfxns.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 3 页
字号:
                     &sig_buffer);                  // User data
        }
        else 
        {
            Output(QUERY_BAD_SIG);
        }
    }

    Input(QUERY_QUESTION,           // Query
          resp,                     // character to read
          RESP_BUFFER_LENGTH);      // maximum characters to read    
    if ((*resp == L'y') ||
        (*resp == L'Y'))
    {
        to_return = TRUE;
    }
    else 
    {
        to_return = FALSE;
    }

    if (resp)
    {
        FreePool(resp);
    }

    Output(L"\n\n");   // give a couple of blank lines for readability purpose

    // I don't know how to clear the screen.....


    // Clear the screen by writing a form-feed '\f'.
    //query_buffer[0]= '\f';
    //AuthWriteConsoleString(
    //    query_buffer,   // msgBuffer
    //    1);             // msgLength

    return to_return;

} // QueryUserAuthorization

///////////////////////////////////////////////////////////////////////////////
// Function Name:  AppendToString
//
// Description:
//     This  internal  function  appends  the indicated bytes to the end of the
//     accumulated string.
//
// Parameters:
//     currentString - (IN OUT) The accumulated string so far
//     newString     - (IN)     The buffer containing contents to be added
//     newLength     - (IN)     Number of bytes to be added
//
// Returns:
//     TRUE if there was room to add the newString.  Otherwise the function
//     returns FALSE and currentString is not modified.
///////////////////////////////////////////////////////////////////////////////
static
BOOLEAN
AppendToString(
    IN OUT  ACCUMULATED_STRING      *currentString,
    IN      CHAR16                  *newString, 
    IN      UINT32                  newLength
    )
{
    BOOLEAN      to_return;
    UINT32       current_length = currentString->length;
    UINT16       *target_buffer = currentString->buffer;

    if (current_length + newLength > currentString->maxLength) 
    {
        to_return = FALSE;
    }
    else 
    {
        UINT32 i;

        to_return = TRUE;
        for (i=0; i<newLength; i++) 
        {
            target_buffer[current_length + i] = newString[i];
        }
        currentString->length += newLength;
    }

    return to_return;
    
} // AppendToString



///////////////////////////////////////////////////////////////////////////////
// Basic Certificate-parsing functions
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// The following is a small collection of types and procedures that are used to
// extract  a  minimal amount of information from a certificate, in particular,
// some  or  all  of  the  digital  signature bit string.  These procedures are
// designed  to  handle  a  DER-encoded  PKCS-6  ExtendedCertificate or a X.509
// Certificate.   From  the  point  of  view  of  these procedures, the overall
// structure of these two types is basically the same, consisting of:
//
// SEQUENCE {
//   SEQUENCE {
//     -- main contents of certificate
//   }
//   SEQUENCE {
//     -- signature algorithm identifier and parameters
//   }
//   signature  BIT STRING
// }
//
// PKCS-6   and   X.509  certificate  definitions  are  described  in  "PKCS#6:
// Extended-Certificate  Syntax  Standard".  A useful explanation of the syntax
// notation and a guide to the BER/DER encoding of certificates can be found in
// "A  Layman's  Guide  to  a  Subset  of  ASN.1, BER, and DER".  Both of these
// documents can be retrieved online through the URL:
//
//     http://www.rsa.com/rsalabs/pubs/PKCS/index.html
//
// Another  extensive  and  readable explanation of X.509v3 certificates is the
// "X.509 Style Guide", which can be found at the URL:
//
//     http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
//
///////////////////////////////////////////////////////////////////////////////





///////////////////////////////////////////////////////////////////////////////
// Type Name: CERT_SCAN_STATE, CERT_SCAN_STATE_PTR
//
// Description:
//     This internal type is used by the collection of procedures that
//     scan through a certificate.  The type keeps track of how far the
//     scan has proceeded.  This type is only intended to be manipulated
//     by those procedures.
//
// Definitions:
//     certBuffer    - A pointer to the in-memory copy of the certificate data
//     certLength    - The  length,  in  bytes,  of  the  in-memory copy of the
//                     certificate data
//     currentOffset - The  current  offset,  in  bytes, of the next byte to be
//                     examined in the certificate buffer.
///////////////////////////////////////////////////////////////////////////////
typedef
struct tag_CERT_SCAN_STATE {
    UINT8       *certBuffer;
    UINT32      certLength;
    UINT32      currentOffset;
} CERT_SCAN_STATE;



///////////////////////////////////////////////////////////////////////////////
//  Function Name: GetSignatureFromCert
//
//  Description:
//      This  internal function extracts and returns up to the indicated number
//      of   bytes   of   the   raw   signature   BIT   STRING  from  a  PKCS-6
//      ExtendedCertificateOrCertificate.
//
//  Parameters:
//      cert      -  (IN) Supplies the certificate to be examined
//      maxLength -  (IN) Supplies the maximum number of bytes of signature BIT
//                        STRING that may be returned.
//      length    - (OUT) Returns  the  number of bytes of signature BIT STRING
//                        that were retrieved if the function is successful.
//      signature - (OUT) Returns  the  signature  BIT  STRING  contents if the
//                        function is successful.
//
//  Returns:       
//      TRUE  if  successful,  otherwise the function returns FALSE and
//      the OUT parameters are undefined.
//
///////////////////////////////////////////////////////////////////////////////
static
BOOLEAN
GetSignatureFromCert(
    IN   EFI_BIS_DATA   *cert,
    IN   UINT32         maxLength,
    OUT  UINT32         *length,
    OUT  UINT8          *signature)
{
    CERT_SCAN_STATE     scanState;
    BOOLEAN             ok_so_far;
    UINT8               tag;
    UINT32              sig_length;

    scanState.certBuffer    = cert->Data;
    scanState.certLength    = cert->Length;
    scanState.currentOffset = 0;
    
    // Extract and check the outer sequence tag
    ok_so_far = ExtractTag(
        & scanState,  // scanState
        & tag);       // tag
    if (ok_so_far) 
    {
        // The  first  tag  should  be  either  0x30  (sequence)  for  a  X.509
        // certificate  or 0xA0 (implicit context-specific contructed id 0) for
        // a  PKCS-6  ExtendedCertificate.   In  either  case, the tag actually
        // represents the outer SEQUENCE.
        #define BISCERT_X509_OUTERTAG       (0x30)
        #define BISCERT_PKCS6_EXT_OUTERTAG  (0xA0)
        if ((tag != BISCERT_X509_OUTERTAG) &&
            (tag != BISCERT_PKCS6_EXT_OUTERTAG)) 
        {
            ok_so_far = FALSE;
        }
    }
    
    // Extract and ignore the outer length
    if (ok_so_far) 
    {
        UINT32 dont_care;
        ok_so_far = ExtractLength(
            & scanState,    // scanState
            & dont_care);   // length
    }

    // Skip the main Certificate body sequence
    if (ok_so_far) 
    {
        ok_so_far = SkipSequence(
            & scanState);  // scanState
    }

    // Skip the signature algorithm identifier sequence
    if (ok_so_far) 
    {
        ok_so_far = SkipSequence(
            & scanState);  // scanState
    }

    // Remainder  should  be  a  Universal,  Primitive, BIT STRING which is the
    // signature.  Check and extract it.
    if (ok_so_far) 
    {
        ok_so_far = ExtractTag(
            & scanState,  // scanState
            & tag);       // tag
    }
    // The tag should be 0x03, representing a BIT STRING
    #define BISCERT_BIT_STRING_TAG   (0x03)
    if (ok_so_far) 
    {
        if (tag != BISCERT_BIT_STRING_TAG) 
        {
            ok_so_far = FALSE;
        }
    }
    if (ok_so_far) 
    {
        ok_so_far = ExtractLength(
            & scanState,    // scanState
            & sig_length);  // length
    }
    // Check containment of the BIT STRING contents
    if (ok_so_far) 
    {
        ok_so_far = IsWithinBuffer(
            & scanState,  // scanState
            sig_length);  // numBytes
    }
    // First  byte  of  BIT STRING contents tells how many non-significant bits
    // are  in  the  last  byte of the BIT STRING bits.  We simply ignore this,
    // skip it, and reduce our expected remaining content length accordingly.
    if (ok_so_far) 
    {
        scanState.currentOffset ++;
        sig_length --;
        // Require at least one byte of actual signature BIT STRING bits
        if (sig_length < 1) 
        {
            ok_so_far = FALSE;
        }
    }
    if (ok_so_far) 
    {
        UINT32  bytes_to_copy;
        UINT32  start_offset;
        UINT32  i;

        bytes_to_copy = maxLength;
        if (bytes_to_copy > sig_length) 
        {
            bytes_to_copy = sig_length;
        }
        start_offset = scanState.currentOffset;
        for (i=0; i<bytes_to_copy; i++) 
        {
            signature[i] = cert->Data[start_offset + i];
        }
        scanState.currentOffset += sig_length;  // for consistency
        * length = bytes_to_copy;
    }

    return ok_so_far;
    
} // GetSignatureFromCert

///////////////////////////////////////////////////////////////////////////////
//  Function Name: SkipSequence
//
//  Description:
//      This   internal  function  scans  past  a  SEQUENCE  in  the  indicated
//      certificate.   It  does  not  extract  and return any values.  The scan
//      state is updated appropriately.
//
//      The scan state must be pointing to the beginning of the SEQUENCE (i.e.,
//      the  SEQUENCE  type  tag)  when called.  When this function returns the
//      scan state points to the next byte past the SEQUENCE content.
//
//  Parameters:
//      scanState - (IN OUT) Holds  information  about  the certificate and the
//                           state of the scan
//
//  Returns:       
//      TRUE if successful, otherwise FALSE.
//
///////////////////////////////////////////////////////////////////////////////
static
BOOLEAN
SkipSequence(
    IN OUT CERT_SCAN_STATE      *scanState
    )
{
    UINT32          seq_len;
    UINT8           tag;
    BOOLEAN         ok_so_far;

    ok_so_far = ExtractTag(
        scanState,  // scanState
        & tag);     // tag
    if (ok_so_far) 
    {
        // Tag must be 0x30 for sequence
        #define BISCERT_SEQUENCE_TAG  (0x30)
        if (tag != BISCERT_SEQUENCE_TAG) 
        {
            ok_so_far = FALSE;
        }
    }
    if (ok_so_far) 
    {
        ok_so_far = ExtractLength(
            scanState,   // scanState
            & seq_len);  // length
    }
    if (ok_so_far) 
    {
        // check containment of skipped sequence content bytes
        ok_so_far = IsWithinBuffer(
            scanState,  // scanState
            seq_len);   // numBytes
    }
    if (ok_so_far) 
    {
        // skip the sequence content bytes
        scanState->currentOffset += seq_len;
    }

    return ok_so_far;
    
} // SkipSequence


///////////////////////////////////////////////////////////////////////////////
//  Function Name: ExtractTag
//
//  Description:
//      This  internal  function  extracts  and  returns  a  type  tag from the
//      indicated certificate.  The scan state is updated appropriately.
//
//      The  scan  state must be pointing to the beginning of the type tag when
//      called.   When  this function returns the scan state points to the next
//      byte past the type tag.
//
//  Parameters:
//      scanState - (IN OUT) Holds  information  about  the certificate and the
//                           state of the scan
//      tag       - (OUT)    Returns  the  retrieved  tag  if  the  function is
//                           successful.
//
//  Returns:       
//      TRUE if successful, otherwise FALSE.
//
///////////////////////////////////////////////////////////////////////////////
static
BOOLEAN
ExtractTag(
    IN OUT CERT_SCAN_STATE      *scanState,
    OUT    UINT8 *              tag
    )
{
    BOOLEAN         ok_so_far;
    UINT8           temp_tag;
    
    // The first byte of a type tag is as follows:
    //   8   7   6   5   4   3   2   1
    // +---+---+---+---+---+---+---+---+
    // | C C   |P/C| ID Code           |
    // +---+---+---+---+---+---+---+---+
    //   CC    is the "class", meaning:
    //   00    Universal
    //   01    Application-specific
    //   10    Context-specific
    //   11    Private
    //
    //   P/C   indicates Primitive or Constructed:
    //   0     Primitive type
    //   1     Constructed type
    //
    //   ID  Code  is a type identifier code.  The special identifier code 0x1F
    //   indicates  that  the  type  tag  extends into additional bytes.  We'll
    //   simply  report  a  failure for this since we don't expect to encounter
    //   any such type tags.
    #define BISCERT_IDCODE_MASK        (0x1F)
    #define BISCERT_EXTENDED_TYPE_TAG  (0x1F)

    ok_so_far = IsWithinBuffer(
        scanState,  // scanState
        1);         // numBytes
    if (ok_so_far) 
    {
        temp_tag = scanState->certBuffer[scanState->currentOffset];
        * tag = temp_tag;
        scanState->currentOffset ++;
        if ((temp_tag & BISCERT_IDCODE_MASK) == BISCERT_EXTENDED_TYPE_TAG) 
        {
            ok_so_far = FALSE;  // fail due to expanding tag
        }
    }

    return ok_so_far;
    
} // ExtractTag

///////////////////////////////////////////////////////////////////////////////
//  Function Name: ExtractLength
//
//  Description:
//      This  internal  function  extracts  and returns a length value from the
//      indicated certificate.  The scan state is updated appropriately.
//
//      The  scan  state  must be pointing to the beginning of the length value

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -