I am currently building a social networking site for a client and I expressed things this way
CREATE TABLE [dbo].[PersonFriend] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Timestamp] DATETIME NOT NULL,
[ChangeUser] NVARCHAR (200) NOT NULL,
[FriendStatusId] TINYINT NOT NULL,
[Person1Id] INT NOT NULL,
[Person2Id] INT NOT NULL,
[Person1RequestTimestamp] DATETIME NOT NULL,
[Person2AcknowledgeTimestamp] DATETIME NULL
);
Each person is stored in the Person table (imagine that). The Person1Id and Person2Id fields are FK to the person table. I keep a status list in the FriendStatus table for covering whether something has been request, accepted, denied, ignored etc. The Timestamp field is standard in my design to indicate record creation (it is a pattern thing that is used in by base persistence class) and its kind of duplicated in this table as the Person1RequestTimestamp contains the same data. I also capture when the Person2 saw the request and made an action (which gets indicated in FriendStatusId) on it and store that in the Person2AcknowledgeTimestamp).
One of the core assumptions of this design can be stated that Person1 requested friendship of Person2 - if that friendship is accepted then the friendship is considered mutual.