How to convert net.Conn into io.ReadWriteCloser Golang

127 Views Asked by At

I am trying to run this sample application, https://github.com/salrashid123/tpm2/blob/master/sign_with_rsa/main.go

which uses /dev/tpm0 file which is available where the real tpm connected. This code works fine in an ubuntu host where I have real tpm 2.0 and tpm2-tools installed.

But I am trying to run the same application with tpm2.0 simulator installed in a VM. I have installed simulator from, https://jaist.dl.sourceforge.net/project/ibmswtpm2/ibmtpm1661.tar.gz

it runs great and able to execute tpm commands like, tpm2_pcrread successfully. But not able to run the above sample application here. if you look the below snippet from the sample application,

    rwc, err := tpm2.OpenTPM(*tpmPath)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Can't open TPM %s: %v", *tpmPath, err)
        os.Exit(1)
    }

they get readwritecloser instance by opening the tpm file which is /dev/tpm0. for a simulator, there is no such file. It run as a server client socket.

 service tpm-server status
● tpm-server.service - TPM2.0 Simulator Server daemon
     Loaded: loaded (/lib/systemd/system/tpm-server.service; disabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-09-28 13:52:23 IST; 7h ago
   Main PID: 14256 (tpm_server)
      Tasks: 3 (limit: 4594)
     Memory: 848.0K
     CGroup: /system.slice/tpm-server.service
             └─14256 /usr/local/bin/tpm_server

Sep 28 16:04:40  tpm_server[14256]: Command IPv4 client accepted
Sep 28 16:04:40  tpm_server[14256]: TPM command server listening on port 2321
Sep 28 16:07:57  tpm_server[14256]: Command IPv4 client accepted
Sep 28 16:07:57  tpm_server[14256]: Unrecognized TPM interface command 80020000
Sep 28 16:07:57  tpm_server[14256]: TPM command server listening on port 2321
Sep 28 16:25:39  tpm_server[14256]: Command IPv4 client accepted
Sep 28 16:25:39  tpm_server[14256]: Unrecognized TPM interface command 80020000
Sep 28 16:25:39  tpm_server[14256]: TPM command server listening on port 2321
Sep 28 16:31:33  tpm_server[14256]: Command IPv4 client accepted
Sep 28 16:31:33  tpm_server[14256]: **TPM command server listening on port 2321**

Server is listening on port 2321.

So I have tried modifying the above code piece into,

conn, err := net.Dial("tcp", "10.0.84.68:2321")
if err != nil {
    log.Fatalf("Error connecting to TPM simulator: %v", err)
}
defer conn.Close()

// Wrap the net.Conn in an io.ReadWriteCloser
//rwc := conn.(io.ReadWriteCloser)
rwc := io.ReadWriteCloser(conn)

I don't know this is a correct way of converting net.Conn into io.ReadWriteCloser.

while running the app, it throws below log,

./main 
Error creating Primary read tcp 10.0.84.68:50900->10.0.84.68:2321: read: connection reset by peer

server log shows,

Sep 28 16:07:57  tpm_server[14256]: TPM command server listening on port 2321
Sep 28 16:25:39  tpm_server[14256]: Command IPv4 client accepted
Sep 28 16:25:39  tpm_server[14256]: 

Unrecognized TPM interface command 80020000

Sep 28 16:25:39  tpm_server[14256]: TPM command server listening on port 2321

Below is the server side code where it throws the above error, (look at the switch case - default)

bool
TpmServer(
      SOCKET           s
      )
{
    uint32_t             length;
    uint32_t             Command;
    uint8_t              locality;
    bool                 OK;
    int                  result;
    int                  clientVersion;
    _IN_BUFFER           InBuffer;
    _OUT_BUFFER          OutBuffer;
    for(;;)
    {
        OK = ReadBytes(s, (char*)&Command, 4);
        // client disconnected (or other error).  We stop processing this client
        // and return to our caller who can stop the server or listen for another
        // connection.
        if(!OK)
        return true;
        Command = ntohl(Command);
        switch(Command)
        {
          case TPM_SIGNAL_HASH_START:
            _rpc__Signal_Hash_Start();
            break;
          case TPM_SIGNAL_HASH_END:
            _rpc__Signal_HashEnd();
            break;
          case TPM_SIGNAL_HASH_DATA:
            OK = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
            if(!OK) return true;
            InBuffer.Buffer = (uint8_t *)InputBuffer;
            InBuffer.BufferSize = length;
            _rpc__Signal_Hash_Data(InBuffer);
            break;
          case TPM_SEND_COMMAND:
            OK = ReadBytes(s, (char*)&locality, 1);
            if(!OK)
            return true;
            OK = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
            if(!OK)
            return true;
            InBuffer.Buffer = (uint8_t *)InputBuffer;
            InBuffer.BufferSize = length;
            OutBuffer.BufferSize = MAX_BUFFER;
            OutBuffer.Buffer = (_OUTPUT_BUFFER)OutputBuffer;
            // record the number of bytes in the command if it is the largest
            // we have seen so far.
            if(InBuffer.BufferSize > CommandResponseSizes.largestCommandSize)
            {
                CommandResponseSizes.largestCommandSize = InBuffer.BufferSize;
                memcpy(&CommandResponseSizes.largestCommand,
                   &InputBuffer[6], sizeof(uint32_t));
            }
            _rpc__Send_Command(locality, InBuffer, &OutBuffer);
            // record the number of bytes in the response if it is the largest
            // we have seen so far.
            if(OutBuffer.BufferSize > CommandResponseSizes.largestResponseSize)
            {
                CommandResponseSizes.largestResponseSize
                = OutBuffer.BufferSize;
                memcpy(&CommandResponseSizes.largestResponse,
                   &OutputBuffer[6], sizeof(uint32_t));
            }
            OK = WriteVarBytes(s,
                       (char*)OutBuffer.Buffer,
                       OutBuffer.BufferSize);
            if(!OK)
            return true;
            break;
          case TPM_REMOTE_HANDSHAKE:
            OK = ReadBytes(s, (char*)&clientVersion, 4);
            if(!OK)
            return true;
            if(clientVersion == 0)
            {
                printf("Unsupported client version (0).\n");
                return true;
            }
            OK &= WriteUINT32(s, ServerVersion);
            OK &= WriteUINT32(s, tpmInRawMode
                      | tpmPlatformAvailable | tpmSupportsPP);
            break;
          case TPM_SET_ALTERNATIVE_RESULT:
            OK = ReadBytes(s, (char*)&result, 4);
            if(!OK)
            return true;
            // Alternative result is not applicable to the simulator.
            break;
          case TPM_SESSION_END:
            // Client signaled end-of-session
            return true;
          case TPM_STOP:
            // Client requested the simulator to exit
            return false;
          default:
            **printf("Unrecognized TPM interface command %d\n", (int)Command);**
            return true;
        }
        OK = WriteUINT32(s, 0);
        if(!OK)
        return true;
    }
}

What am doing wrong from client side? meaning, from sample application side? anyone has any idea?

thanks in advance..!

0

There are 0 best solutions below