Linux——密鑰管理Socket

 

緬懷Stevens大師。

最好的參考資料:

1.師從互聯網。

2.http://man.cx/pf_key(7p):這個man命令並不是Linux的,應該是BSD的,但原理相同。

3.UNP v1第19章 。

4.http://www.ibm.com/developerworks/cn/linux/l-key-retention.html

http://qq164587043.blog.51cto.com/261469/201152

第一條:概述

人如期名,密鑰管理Socket,就是用來管理密鑰的(廢話^_^)。 

密鑰(key)是一組密碼學數據、身份驗證標記或某些相似的元素,它在內核中由 struct key 表示。在 Linux 內核源代碼中,struct key 是在 include/linux/key.h 下定義的。

第二條:密鑰管理socket

密鑰管理描述符

int sockfd=socket(PF_KEY,SOCK_RAW,PF_KEY_V2);

密鑰管理消息

所有密鑰管理消息都是由頭部和可選的擴展數據組成

struct sadb_msg {/* sizeof(struct sadb_msg) == 16 *///頭部

 __u8 sadb_msg_version;//PF_KEY_V2

 __u8 sadb_msg_type;//密鑰管理消息的類型

 __u8 sadb_msg_errno;//error indication

 __u8 sadb_msg_satype;//SA類型(security association)

 __u16 sadb_msg_len;//length of header(頭部) + extensions/8(數據)

 __u16 sadb_msg_reserved;//zero on transmit ,ifnored on received

 __u32 sadb_msg_seq;//sequence number

 __u32 sadb_msg_pid;//process ID of source or dest

} __attribute__((packed));

sadb_msg_type:取值如下

#define SADB_RESERVED 0   

#define SADB_GETSPI 1  /* Get a new SPI value from the system. */分配一個用於創建SADB表項的SPI

#define SADB_UPDATE 2  /* Update an SA. */更改一個不完備的SADB表項

#define SADB_ADD 3  /* Add a fully-formed SA. */增加一個完整的SADB表項

#define SADB_DELETE 4  /* Delete an SA. */刪除一個SADB表項

#define SADB_GET 5   /* Get an SA */獲取一個SADB表項

#define SADB_ACQUIRE 6   /* Kernel needs a new SA. */請求創建一個SADB表項

#define SADB_REGISTER 7   /* Register to receive ACQUIRE messages. */註冊成 SADB_ACQUIRE的應答者

#define SADB_EXPIRE 8    /* SA has expired. */通知某個SADB表項已經期滿

#define SADB_FLUSH 9   /* Flush all SAs. */沖刷整個SADB

#define SADB_DUMP 10   /* Get all SAs. (Unreliable) */傾瀉出SADB(調試用)

#define SADB_X_PROMISC 11 /* Listen promiscuously */

以上1到10中的10個值只有8是隻能由內核發往用戶空間,其他9個都可在用戶和內核之間雙向傳遞。

sadb_msg_satype:取值如下

/* Security Association types */

#define SADB_SATYPE_UNSPEC 0 //未指明;僅限於請求消息

#define SADB_SATYPE_AH 2  //IPsec安全頭部

#define SADB_SATYPE_ESP 3  //IPsec安全淨荷封裝

#define SADB_SATYPE_RSVP 5  //RSVP認證

#define SADB_SATYPE_OSPFV2 6 // OSPFv2 認證

#define SADB_SATYPE_RIPV2 7  //RIPv2 認證

#define SADB_SATYPE_MIP 8  //可移動IP認證

#define SADB_X_SATYPE_IPCOMP 9 

#define SADB_SATYPE_MAX 9

 

每一種擴展數據類型都有專門對應的數據結構類型:

/* Extension Header values */

#define SADB_EXT_RESERVED 0

1.#define SADB_EXT_SA 1  SA 

對應數據結構:

struct sadb_sa {/* sizeof(struct sadb_sa) == 16 */

 __u16 sadb_sa_len;

 __u16 sadb_sa_exttype;

 __be32 sadb_sa_spi;

 __u8 sadb_sa_replay;

 __u8 sadb_sa_state;

 __u8 sadb_sa_auth;

 __u8 sadb_sa_encrypt;

 __u32 sadb_sa_flags;

} __attribute__((packed));

 

 

2.#define SADB_EXT_LIFETIME_CURRENT 2  SA當前生命期

#define SADB_EXT_LIFETIME_HARD 3  SA生命期硬限制

#define SADB_EXT_LIFETIME_SOFT 4   SA生命期軟限制

對應數據結構:

struct sadb_lifetime {/* sizeof(struct sadb_lifetime) == 32 */

__u16 sadb_lifetime_len;

__u16 sadb_lifetime_exttype;

__u32 sadb_lifetime_allocations;

__u64 sadb_lifetime_bytes;

__u64 sadb_lifetime_addtime;

__u64 sadb_lifetime_usetime;

} __attribute__((packed));

3.#define SADB_EXT_ADDRESS_SRC 5   SA宿地址

#define SADB_EXT_ADDRESS_DST 6    SA源地址

#define SADB_EXT_ADDRESS_PROXY 7   SA代理地址

對應數據結構:

struct sadb_address {/* sizeof(struct sadb_address) == 8 */

__u16 sadb_address_len;

__u16 sadb_address_exttype;

__u8 sadb_address_proto;

__u8 sadb_address_prefixlen;

__u16 sadb_address_reserved;

} __attribute__((packed));

 

4.#define SADB_EXT_KEY_AUTH 8  認證密鑰

#define SADB_EXT_KEY_ENCRYPT 9  加密密鑰

對應數據結構:

struct sadb_key {/* sizeof(struct sadb_key) == 8 */

__u16 sadb_key_len;

__u16 sadb_key_exttype;

__u16 sadb_key_bits;

__u16 sadb_key_reserved;

} __attribute__((packed));

 

5.#define SADB_EXT_IDENTITY_SRC 10 宿身份

#define SADB_EXT_IDENTITY_DST 11  源身份

對應數據結構:

struct sadb_ident {/* sizeof(struct sadb_ident) == 16 */

__u16 sadb_ident_len;

__u16 sadb_ident_exttype;

__u16 sadb_ident_type;

__u16 sadb_ident_reserved;

__u64 sadb_ident_id;

} __attribute__((packed));

 

6.#define SADB_EXT_SENSITIVITY 12   SA敏感性

對應數據結構:

struct sadb_sens {/* sizeof(struct sadb_sens) == 16 */

__u16 sadb_sens_len;

__u16 sadb_sens_exttype;

__u32 sadb_sens_dpd;

__u8 sadb_sens_sens_level;

__u8 sadb_sens_sens_len;

__u8 sadb_sens_integ_level;

__u8 sadb_sens_integ_len;

__u32 sadb_sens_reserved;

} __attribute__((packed));

/* followed by:

__u64 sadb_sens_bitmap[sens_len];

__u64 sadb_integ_bitmap[integ_len];  */

 

7.#define SADB_EXT_PROPOSAL 13   得到提議的情形

對應數據結構:

struct sadb_prop {/* sizeof(struct sadb_prop) == 8 */

__u16 sadb_prop_len;

__u16 sadb_prop_exttype;

__u8 sadb_prop_replay;

__u8 sadb_prop_reserved[3];

} __attribute__((packed));

 

8.#define SADB_EXT_SUPPORTED_AUTH 14   得到支持的認證算法

#define SADB_EXT_SUPPORTED_ENCRYPT 15  得到支持的加密算法

對應數據結構:

struct sadb_supported {/* sizeof(struct sadb_supported) == 8 */

__u16 sadb_supported_len;

__u16 sadb_supported_exttype;

__u32 sadb_supported_reserved;

} __attribute__((packed));

 

 

9.#define SADB_EXT_SPIRANGE 16 可接受的SPI值範圍

對應數據結構:

struct sadb_spirange {/* sizeof(struct sadb_spirange) == 16 */

__u16 sadb_spirange_len;

__u16 sadb_spirange_exttype;

__u32 sadb_spirange_min;

__u32 sadb_spirange_max;

__u32 sadb_spirange_reserved;

} __attribute__((packed));

 

 

第三條:RFC2367

 

組織:中國互動出版網(http://www.china-pub.com/)

RFC文檔中文翻譯計劃(http://www.china-pub.com/compters/emook/aboutemook.htm)

E-mail:[email protected]

譯者:(  )

譯文發佈時間:2002-1-9

版權:本中文翻譯文檔版權歸中國互動出版網所有。可以用於非商業用途自由轉載,但必須

保留本文檔的翻譯及版權信息。

 

 

 

 

Network Working Group                                       D. McDonald

Request for Comments: 2367                                      C. Metz

Category: Informational                                         B. Phan

                                                              July 1998

 

 

PF_KEY Key Management API, Version 2

(RFC2367——PF_KEY Key Management API, Version 2)

 

本備忘錄狀態

 

   This memo provides information for the Internet community.  It does

   not specify an Internet standard of any kind.  Distribution of this

   memo is unlimited.

 

版權聲明

 

   Copyright (C) The Internet Society (1998).  All Rights Reserved.

 

摘要

 

       本文檔提出的通用密鑰管理API不但爲IP安全[Atk95a][Atk95b][Atk95c]而且

   爲其它網絡安全提供服務。做爲可以自由發佈和使用的美國海軍研究實驗室設計實

   現的IPv6和IPsec的一部分,在4.4-Lite BSD內部實現了這個API的第一版。這裏編

   輯成檔有助於其他人採用這個API,這些規定增強了密鑰管理應用程序的可移植性(

   例如:手工設置程序,ISAKMP守護進程,GKMP守護進程,Photuris守護進程或者SKIP

   證書發現協議守護進程)。

 

目錄

 

1 介紹 3

1.1 術語 3

1.2 總體模型 4

1.3 PF_KEY套接口定義 6

1.4 PF_KEY消息行爲概述 7

1.5 共同的PF_KEY操作 7

1.6 PF_KEY和PF_ROUTE之間的區別 8

1.7 名稱空間 8

1.8 手工密鑰 9

2. PF_KEY消息格式 9

2.1 基本消息頭格式 9

2.2 消息頭位對齊和擴展頭 11

2.3 附加的消息域 11

2.4 消息格式的圖例 22

3 符號名 26

3.1 消息類型 26

3.2 安全關聯標誌 35

3.3 安全關聯狀態 35

3.4 安全關聯類型 36

3.5 算法類型 37

3.6 擴展頭值 37

3.7 身份擴展值 38

3.8 敏感度擴展值 39

3.9 提議擴展值 39

4 發展趨勢 39

5. 實例 40

5.1 簡單的IP安全例子 40

5.2 代理IP安全例子 42

5.3 OSPF安全例子 44

5.4 其它 45

6 安全考慮 45

致謝 46

參考 46

放棄聲明 48

作者地址 48

附錄A:混雜模式發送/接收消息擴展 49

附錄B:被動轉換消息擴展 50

附錄C:密鑰管理專用數據擴展 51

附錄D:頭文件樣本 52

附錄E:修改記錄 57

附錄F:版權聲明 60

 

 

 

1 介紹

       PF_KEY是一個新的套接口協議族,用於可信賴的有特權的密鑰管理程序和操作

   系統內部的密鑰管理(這裏指“密鑰引擎”或者安全關聯數據庫(SADB))的通信。密

   鑰引擎和它的構件是一個會話安全屬性的具體表現,也是“安全關聯”的實例。“

   安全關聯”(SA)的概念在RFC2401(原文爲RFC1825現已被代替)中說明。這裏所說的

   PF_KEY和密鑰引擎引用多於加密密鑰,傳統術語“密鑰管理”爲了一致性予以保留。

 

       PF_KEY源於BSD的路由套接字PF_ROUTE([Skl91])的一部分。本文檔說明了PF_KEY

   的第二版本。第一版本爲4.4-Lite BSD UNIX和Cisco ISAKMP/Oakley密鑰管理守護

   進程在NRL IPv6+IPsec Software Distribution的最初的五個alpha測試版中實現。

   版本2擴充和精製了接口。理論上,本文檔定義的消息可以在無套接口的環境應用(

   例如:在兩個直接通信的應用層程序之間),但是這種可能性這裏不做詳細討論。

 

       安全策略在這個接口中慎重地忽略。PF_KEY不是協調全系統安全策略的機制,

   也不想要實施任何密鑰管理策略。PF_KEY的開發者認爲把安全機制(如PF_KEY)和安

   全策略分離是很重要的,這樣允許一個機制很容易的支持多個策略。

 

 

1.1 術語

 

       儘管本文檔不打算成爲實際的因特網標準,本接口用來說明獨特功能的重要性

   的關鍵詞通常大寫。這些詞中的一部分,包括MUST, MAY和SHOULD在文檔RFC2119中

   詳細說明。

 

   - 一致和符合

 

       一致和符合在本規範中具有相同的含義。無論在那種情形,強制執行或者MUST

   指定的條款必須完全貫徹。如果任一強制條款沒有貫徹,那麼具體實現就不符合本

   規範。

 

       本規範也使用很多通常在網絡安全方面使用的術語,其它文檔提供了很多定義

   和背景資料[VK83, HA94, Atk95a]。兩個術語在這裏專門提及:

 

   - (加密/認證)算法

 

       PF_KEY的目的是指一個算法無論是加密還是認證,包含一系列完成SA類型所指

   出的數據包加密或認證的操作。一個PF_KEY算法可以由多個加密算法構成。另一種

   可能,同一基本加密算法可以應用於不同的操作模式或者一些其它不同的實現。這

   些區別,今後命名爲“_算法識別碼_”,以區別不同的PF_KEY算法和同一算法的選

   項。算法識別碼將導致根本不同的安全性質。

 

       例如,DES和3DES使用相同的加密算法,但是它們用法不同並且具有不同的安

   全性質。DES的三次應用被認爲是一個算法識別,因此分爲PF_KEY算法DES和3DES。

   Keyed-MD5和HMAC-MD5使用相同的散列函數,但是構成它們的消息認證編碼不同,

   HAMC的用途就是一個算法識別碼。DES-ECB和DES-CBC是相同的加密算法,但是使用

   不同的模式。模式(例如:鏈式對編碼書)就是一個算法識別。然而,128位密鑰的

   Blowfish與384位密鑰的Blowfish相似,因爲除了算法的工作方式其它相同,因此

   密鑰長度不是算法識別碼。

 

       在IP安全方面,一個首要規則就是無論什麼標記“加密”於ESP變換的部分可

   能就是一個PF_KEY加密算法;無論什麼標記“認證”於AH或者ESP變換的部分可能

   就是一個PF_KEY認證算法。

 

 

1.2 總體模型

 

       這一節描述實現PF_KEY密鑰管理應用程序接口的操作系統的總體模型。這一節

   將要提供有用的背景資料以便理解本文檔的其餘部分。總體模型的介紹不會強迫一

   個PF_KEY具體實現嚴格遵循這一小節討論的概念上的組件。

 

       大多數密鑰管理通常部分或者全部在應用層實現。例如:IPsec的密鑰管理提

   案ISAKMP/Oakley、 GKMP和Photuris都是應用層協議;手動調節也是在應用層完成;

   甚至部分SKIP協議層密鑰管理提案能夠在應用層實現。圖1說明了密鑰管理守護進

   程和PF_KEY之間的關係。密鑰管理守護進程使用PF_KEY與密鑰引擎通信,並且使用

   PF_INET(在IPv6下用PF_INET6)通過網絡與遠端的密鑰管理程序通信。

 

       “密鑰引擎”或者“安全關聯數據庫(SADB)”在內核是一個邏輯實體,可以

   爲不同的安全協議存儲、更新和刪除安全關聯數據。內核中的安全協議(例如:IP

   Security、aka IPsec)利用內核內部的邏輯接口請求並且獲得安全關聯。

 

       在IPsec的情況下,如果按照策略一個特殊的輸出包需要處理,IPsec通過內核

   內部接口從密鑰引擎請求一個合適的安全關聯;如果密鑰引擎有一個合適的SA就分

   配給IPsec使用;如果密鑰引擎沒有,但是密鑰管理程序已經預先指出(通過PF_KEY

   SADB_REGISTER消息)了IPsec可以獲得的安全關聯簇,那麼密鑰引擎請求並建立一個

   安全關聯(通過PF_KEY SADB_ACQUIRE消息)。當密鑰管理守護進程建立一個新的安全

   關聯就會保存在密鑰引擎中以備將來使用。

 

 

                     +----------------+

                     |密鑰管理守護進程|

                     +----------------+

                       |           |

                       |           |

                       |           |                   應用程序

               ======[PF_KEY]====[PF_INET]==========================

                       |           |                   系統內核

               +------------+   +-----------------+

               |  密鑰引擎  |   |     TCP/IP      |

               |    或者    |---|      包括       |

               |    SADB    |   |     IPsec       |

               +------------+   +-----------------+

                                        |

                                   +----------+

                                   | 網絡接口 |

                                   +----------+

 

              圖1: 密鑰關聯程序和PF_KEY的關係

 

 

       爲了獲得好的性能,一些安全協議(如:IP安全)通常會在操作系統內核中實

   現。其它的安全協議(如:OSPFv2密碼認證)在內核外可信的特權程序中實現。圖

   2說明了一個可信的特權路由守護進程使用PF_INET同遠端路由守護進程傳遞路由信

   息,並且使用PF_KEY請求、獲得和刪除路由協議使用的安全關聯。

 

 

                     +---------------+

                     |  路由守護進程 |

                     +---------------+

                       |           |

                       |           |

                       |           |                   應用程序

               ======[PF_KEY]====[PF_INET]==========================

                       |           |                   系統內核

               +------------+   +-----------------+

               |  密鑰引擎  |   |                 |

               |    或者    |---|     TCP/IP      |

               |    SADB    |   |                 |

               +------------+   +-----------------+

                                        |

                                   +----------+

                                   | 網絡接口 |

                                   +----------+

 

        圖2: 可信的程序和PF_KEY的關係

 

 

       當一個在自身內部實現安全協議的可信的特權程序使用密鑰引擎時,操作有所

   不同。在這種情況下,當程序需要安全關聯時向密鑰引擎發送一個PF_KEY SADB_ACQUIRE

   消息,密鑰引擎返回錯誤或者發送同樣的SADB_ACQUIRE消息到一個或者多個可以建

   立所需安全關聯的密鑰管理程序。如以前,密鑰管理守護進程把安全關聯存儲在密

   鑰引擎,可信的特權程序使用一個SADB_GET消息獲得安全關聯。

 

       在一些實現中,策略可能在用戶層實現,儘管如此,實際的加密處理還是在內

   核發生。這樣,策略通信在內核之間,並且用戶層策略可以通過PF_KEY擴展實現,

   或者其它類似機制。本文檔對這樣擴展不做詳細說明。本文檔規定的PF_KEY不支持

   使用PF_KEY配置整個系統的策略。

 

       不可信的客戶端,如:用戶的WEB瀏覽器或者Telnet客戶端不需要使用PF_KEY。

   這裏沒有規定這些不可信客戶端程序請求操作系統的安全服務(例如IPsec)的機

   制。出於安全原因,只有可信的特權程序可以打開PF_KEY套接口。

 

 

1.3 PF_KEY套接口定義

 

       PF_KEY協議族定義在<sys/socket.h>中,與其它的協議族同樣的風格。應用程

   序使用PF_KEY不能依靠關鍵字AF_KEY是否可用,但是內核的實現最好定義AF_KEY。

 

     密鑰管理套接字的建立如下:

 

     #include <sys/types.h>

     #include <sys/socket.h>

     #include <net/pfkeyv2.h>

 

     int s;

     s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);

 

       PF_KEY守護進程目前只能支持SOCK_RAW套接字。協議域必須設置爲PF_KEY_V2,

   否則將返回錯誤EPROTONOSUPPORT。只有可信的特權進程能夠建立PF_KEY套接字。

   UNIX系統的慣例,特權進程是指用戶標識符爲零的進程。在分離式工作站(CMWs)

   或者其它聲稱提供多級安全(MLS)的系統上,一個進程必須擁有“密鑰管理特權”

   才能打開PF_KEY套接字[DIA]。當前沒有上述特權的MLS系統爲了符合本規範必須增

   加上述特權給PF_KEY。一些系統,尤其是在一些流行的個人電腦上,沒有普通用戶

   的概念。這些系統應該設法限制應用程序訪問PF_KEY API。

 

 

1.4 PF_KEY消息行爲概述

 

       一個進程使用PF_KEY套接字發送和接受消息與密鑰引擎相互作用,通過一系列

   預先定義的消息安全關聯信息可以被插入和檢索內核的安全關聯表。在正常情況下,

   所有正確的消息發送至內核並被返回到包括髮送者在內的所有打開的PF_KEY套接字。

   格式錯誤的消息將會造成錯誤,一個實現必須在返回消息給合適的監聽者之前檢查

   消息的正確格式。與路由套接字不同,PF_KEY在返回消息中發送錯誤,不是write()

   或者send()錯誤時的錯誤號字段。PF_KEY消息發送不被保證,尤其在內核或者套接

   字緩存耗盡時,並且消息被丟棄。

 

       一些消息由操作系統產生指出需要那些動作,沒必要響應用戶的任何消息。這

   樣的消息不被所有的PF_KEY套接字接收。這些消息是特定的,因爲它們發生在預期

   的頻率。同樣,一個實現可能更希望限制從內核返回的消息,因爲不是所有的PF_KEY

   套接字在同樣可信的守護進程中。

 

       許多標準的BSD套接字調用在PF_KEY套接字中沒有定義,包括:bind(), connect(),

   socketpair(), accept(),getpeername(), getsockname(), ioctl(), and listen()。

 

 

1.5 共同的PF_KEY操作

 

       將一個新的安全關聯加入內核有兩種基本途徑。最簡單的方法是從應用程序發

   送一個包含所有安全關聯信息的SADB_ADD消息至內核的密鑰引擎。這種方法特別適

   用於手工密鑰管理,這對於IPsec和其它安全協議是必需的。

 

       第二種方法是:應用程序首先使用SADB_GETSPI消息從內核請求一個安全參數

   索引(SPI)值,然後發送一個包含安全關聯數據的SADB_UPDATE消息消息。這種方

   法適用於密鑰管理守護進程,但SPI值需要先於全部安全關聯數據獲得(這樣SPI值

   能夠指出密鑰管理會話的對端)。

 

       使用SADB_DELETE消息可以刪除單個的安全關聯;刪除一類安全關聯或者整個

   內核的安全關聯表用SADB_FLUSH消息。

 

       可信的應用層進程(如routed(8)或者gated(8))可以用SADB_GET消息從內核

   的密鑰引擎獲得一個安全關聯(如RIP SA或者OSPF SA)。

 

       內核或者應用層程序可以使用SADB_ACQUIRE消息請求一個某些應用層密鑰管理

   進程建立並通過SADB_REGISTER消息在內核登記的安全關聯。這個ACQUIRE消息擁有

   一個相關聯的序列號。這個序列號必須在隨後的SADB_GETSPI、SADB_UPDATE和SADB_ADD

   消息中使用,目的是明瞭那一個請求獲得了它的密鑰素材。系列號(下面詳述)類

   似於一個遠程調用的處理標識符。

 

       當一個安全關聯的“軟件週期”或者“硬件週期”期滿時,從內核發送SADB_EXPIRE

   消息至密鑰管理程序。密鑰管理程序以收到的SADB_EXPIRE消息中的軟件週期爲提

   示協商一個替代的安全關聯,這樣在內核使用之前替代的安全關聯已準備好。

 

       SADB_DUMP消息主要是爲了PF_KEY實現程序的調試,並且不能用於平常的PF_KEY

   操作。

 

 

1.6 PF_KEY和PF_ROUTE之間的區別

 

       下面指出路由套接字和PF_KEY之間的區別。曾用路由套接字的程序員將會發現

   兩者之間的差別。

 

   * PF_KEY消息錯誤通常在PF_KEY消息中返回,代替說明write()錯誤的錯誤號。這

     意味着其它PF_KEY套接字監聽者可以知道別的進程的請求失敗,這可用於審計。

     這也意味着讀PF_KEY消息錯誤不能做錯誤檢查。

 

     具體實現可以返回write()操作失敗導致的EINVAL、ENOMEM和ENOBUFS錯誤,也可

     以返回錯誤號。這是最佳處理對於普通錯誤,這樣可以不被其它進程檢測到並接

     收錯誤。應用程序不能依賴於write()調用設置的錯誤,但是應該檢查這些錯誤,

     並用適當的方式處理。

 

   * 全部消息不是總是有返回消息。SADB_ADD消息就是一個例子。

 

   * PID不是由內核設定。發起消息的進程必須把sadb_msg_pid設置成自己的PID。如

     果內核發起一個消息,sadb_msg_pid必須設置爲0。源消息的應答應該有源消息的

     PID(如:內核對SADB_ADD的響應,PID應設置成源SADB_ADD消息的PID值)。

 

 

1.7 名稱空間

 

       全部PF_KEYv2預定義和結構定義在頭文件<net/pfkeyv2.h>中說明,有一個例

   外:“PF_KEY”(如果包括“AF_KEY”有兩個)在頭文件<sys/socket.h>中說明。

   所有的PF_KEYv2預定義以前綴“SADB_”開始,所有的結構名以“sadb_”開始,有

   兩個例外:“PF_KEY_V2”和“PFKEYV2_REVISION”。

 

       “PFKEYV2_REVISION”是一個日期編碼值就像由POSIX和X/Open定義的固定

   值,當前值是199806L,1998是年,06是月份。

 

       本文檔沒有描述的符號或結構沒有作者的明確許可,在<net/pfkeyv2.h>中的

   定義不能使用PF_KEYv2的命名空間,任何本規範沒有描述的使用PF_KEYv2名稱空間

   的符號或結構必須以“SADB_X_”或“sadb_x_”開始。一個未能遵從這些規則的實

   現是不適應本規範的並且不能有什麼要求。這些規則也適用於任何可能包含

<net/pfkeyv2.h>

   的文件。這個規定可以保證實現者不會遇到定義衝突。

 

 

1.8 手工密鑰

 

       與4.4-Lite BSD的PF_ROUTE套接口相同,本接口允許一個程序從頭到尾完全支

   配內核中的安全關聯來實現PF_KEY。PF_KEY的實現必須具有一些手工接口,能提供

   這裏描述的PF_KEY接口的所有功能。

 

 

2. PF_KEY消息格式

 

       PF_KEY消息由一個基本的消息頭和一些可選的附加數據段組成,附加的數據段

   格式由消息類型決定。

 

       PF_KEY消息目前不要求任何具體非網絡的多字節數據段的順序。除非其它指定

   (如SPI)數據段必須是主機字節序。

 

 

2.1 基本消息頭格式

 

       PF_KEY消息由基本消息頭和隨後的安全關聯的具體數據組成,數據段的類型和

   長度由統一的類型長度編碼指定。

 

       基本消息頭使用POSIX類型,格式如下。爲了直觀,各字段對齊排列。

 

           struct sadb_msg {

                   uint8_t sadb_msg_version;

                   uint8_t sadb_msg_type;

                   uint8_t sadb_msg_errno;

                   uint8_t sadb_msg_satype;

                   uint16_t sadb_msg_len;

                   uint16_t sadb_msg_reserved;

                   uint32_t sadb_msg_seq;

                   uint32_t sadb_msg_pid;

           };

           /* sizeof(struct sadb_msg) == 16 */

 

   sadb_msg_version

                   PF_KEY消息的版本號,必須設置爲PF_KEY_V2。否則,write()調

                   用將失敗並報參數錯誤(EINVAL)。另外,應用程序不能理解從

                   內核收到的消息的格式,運行狀態將無法確定。

 

   sadb_msg_type   標識消息的類型。有效的消息類型稍後說明。

 

   sadb_msg_errno  消息的發送者應設置此項爲零。如果出現錯誤,消息的應答者在

                   此存放錯誤碼。包括應用層的消息應答(如:應用層協商失敗,

                   將返回錯誤號)。

 

   sadb_msg_satype 標識安全關聯的類型。有效的安全關聯類型在<net/pfkeyv2.h>

                   中定義。本文檔稍後列舉目前的安全關聯類型。

 

   sadb_msg_len    包含消息的整個長度,64位字對齊,包括基本頭長度和附加數據,

                   幷包括可能存在的任何填充和額外空間。除非其它情況,所有其

                   它長度字段也是64位字對齊。

 

                   用戶到內核的消息,這一項必須檢驗。如果檢驗失敗必須返回錯

                   誤EMSGSIZE。內核到用戶的消息,大小不匹配就像用戶未提供足

                   夠的緩存。在這種情況下,用戶程序可以丟棄這個消息,但是應

                   努力析取超出的數據。                   

 

   sadb_msg_reserved

                   保留值。消息發送者必須設置爲零。本文檔中所有的保留值含義

                   與此相同。

 

   sadb_msg_seq    包含消息的序列號。這一項必須連同sadb_msg_pid唯一確定一個

                   進程的請求。發送者負責設置這一項並負責匹配一個請求的

sadb_msg_seq

                   (如:SADB_ACQUIRE)。

 

                   這一項就像一個同遠端程序調用實現的交易ID

 

   sadb_msg_pid    識別消息的發起進程或者消息的目的進程。例如:如果ID未2112

                   的進程發送一個SADB_UPDATE消息至內核,必須設置本項爲2112,

                   並且內核在自己的應答消息中設置本項爲2112。本項連同

sadb_msg_seq

                   能夠唯一確定一個進程的請求。

 

                   通常用一個32位值保存操作系統的進程ID。

 

 

2.2 消息頭位對齊和擴展頭

 

       基本的消息頭長度是64位的倍數,如果頭是64位對齊緊隨其後在內存中的數據

   也是64位對齊。一些隨後的擴展頭具有64位域,結果需要64位值的環境中進行對齊。

 

       PF_KEY版本2的算法和長度的基本單位是64比特。所以:

 

     * 所有的擴展頭,包括sadb_ext覆蓋域,必須是64比特的整數倍。

 

     * 所有可變的數據長度必須適當填充,從而使消息長度是64比特的整數倍。

 

     * 所有的長度字段,除非特別指定,以64比特爲單位。

 

     * 執行程序可以安全的以8和64比特爲單位直接存取消息而沒有定位錯誤的風險。

 

       所有PF_KEYv2結構封裝並且已經有意進行填充。具體實現不能往本文檔定義的

   結構中插入任何額外字段,包括隱藏的填充。並且禁止未改變擴展頭類型就“擴展”

   和“增強”已存在的結構頭。本文檔所定義的每一個結構已標明字節大小,防備無

   聲明的填充。具體實現中的結構必須符合所列出的結構大小。

 

 

2.3 附加的消息域

 

       基本消息頭後的附加數據由一系列長度-類型值字段組成。開始的32比特固定

   格式如下:

 

           struct sadb_ext {

                   uint16_t sadb_ext_len;

                   uint16_t sadb_ext_type;

           };

           /* sizeof(struct sadb_ext) == 4 */

 

   sadb_ext_len    擴展頭64位字對齊的長度。

 

   sadb_ext_type   擴展頭類型。具體值稍後詳述,零爲保留值。

 

       擴展頭的類型包括:安全關聯、生存期、地址、密鑰、身份、敏感度、提議和

   支持項。一個消息中必須只能有一個擴展類型的實例(例如:基本頭、密鑰、生存

   期,密鑰是禁止的)。如果一個消息中有兩個擴展類型將返回EINVAL錯誤。具體實

   現可以給“擴展頭值”一節介紹的擴展項排序。

 

       如果遇到一個未知的擴展類型,必須忽略該擴展項。應用程序使用本文檔未說

   明的擴展頭必須有其它的系統組件不做處理的準備。同樣,如果應用程序遇到一個

   從內核來的未知擴展,必須有能力正常運轉。而且內核產生額外的擴展頭類型不能

   指望應用程序也能理解額外的擴展頭類型。

 

       所有的擴展項定義包括兩個字段(長度和類型),因爲它們代表一類擴展(就

   像sockaddr_in和sockaddr_in6代表一類套接字地址)。在一個消息中sadb_ext頭

   最少含有4字節的擴展頭數據,只有4字節也沒問題。

 

       在一個PF_KEY具體實現中,本節所列的擴展項必須全部實現。

 

 

2.3.1 安全關聯擴展項

 

       安全關聯擴展項說明了單個安全關聯的詳細數據。當傳遞的是控制消息(例如

   SADB_FLUSH或SADB_REGISTER)中沒有這個擴展項,並且SADB_ACQUIRE消息中也沒有。

 

           struct sadb_sa {

                   uint16_t sadb_sa_len;

                   uint16_t sadb_sa_exttype;

                   uint32_t sadb_sa_spi;

                   uint8_t sadb_sa_replay;

                   uint8_t sadb_sa_state;

                   uint8_t sadb_sa_auth;

                   uint8_t sadb_sa_encrypt;

                   uint32_t sadb_sa_flags;

           };

           /* sizeof(struct sadb_sa) == 16 */

 

   sadb_sa_spi     安全關聯的安全參數索引。儘管是一個32位的字段,某些類型的

                   安全關聯的SPI或密鑰標識長度可能少於32位。在這種情況下,將

                   存儲有意義的位,不需要的位清零。本字段必須是網絡字節序。

 

   sadb_sa_replay  如果不爲零表示重放窗口大小,如果爲零表示沒有重放窗口在使

                   用。

 

   sadb_sa_state   安全關聯狀態。稍後詳述。

 

   sadb_sa_auth    安全關聯將要使用的認證算法。有效的認證算法稍後詳述。如果

                   爲零表示不使用認證算法。

 

   sadb_sa_encrypt 安全關聯將要使用的加密算法。有效的加密算法稍後詳述。如果

                   爲零表示不使用加密算法。

 

   sadb_sa_flags   按位操作的安全關聯選項。稍後詳述。

 

       內核必須檢查這些值的正確性。例如:IPsec AH沒有認證算法可能是一個錯誤。

 

       在一些消息中,安全關聯擴展項的一些字段的值應當忽略。

 

 

2.3.2 生存期擴展項

 

       生存期擴展項說明了安全關聯的一個或多個生存週期變量。如果生存期擴展項

   不存在,則安全關聯是永久有效的。安全關聯應具有某種生存期,生存期分三種:

   HARD指硬件限定期滿;SOFT指軟件限定期滿;CURRENT指特定的安全關聯的當前狀

   態。生存期擴展項的結構如下:

 

           struct sadb_lifetime {

                   uint16_t sadb_lifetime_len;

                   uint16_t sadb_lifetime_exttype;

                   uint32_t sadb_lifetime_allocations;

                   uint64_t sadb_lifetime_bytes;

                   uint64_t sadb_lifetime_addtime;

                   uint64_t sadb_lifetime_usetime;

           };

           /* sizeof(struct sadb_lifetime) == 32 */

 

   sadb_lifetime_allocations

                   對於CURRENT,安全關聯分配的不同的連接數、端點或流量;對

                   於HARD和SOFT,指在期滿前安全關聯可以分配的連接數、端點或

                   流量。

 

 

   sadb_lifetime_bytes

                   對於CURRENT,使用這個安全關聯處理了多少個字節;對於HARD

                   和SOFT,在期滿之前,可以處理的字節數。

 

   sadb_lifetime_addtime

                   對於CURRENT,指安全關聯建立時的時間,以秒計;對於HARD和

                   SOFT,指安全關聯建立後在期滿之前的時間。

 

                   對於這樣的時間字段,系統假定64位可以足夠存放POSIX時間類

                   型值。如果不夠,這個字段必須重新修訂。

 

   sadb_lifetime_usetime

                   對於CURRENT,指安全關聯第一次使用的時間,以秒計;對於HARD

                   和SOFT,指安全關聯第一次使用後在期滿之前的時間。

 

       安全關聯的各項生存期指的關係是邏輯或,這意味着如果字節和時間值,或者

   多項時間值被檢查,第一個符合範圍的值將導致生存期期滿。

 

 

2.3.3 地址擴展項

 

       地址擴展項說明一個或多個與安全關聯有關的地址。當安全關聯擴展項存在時

   源和目的地址的擴展項必須存在。地址擴展項的格式如下:

 

           struct sadb_address {

                   uint16_t sadb_address_len;

                   uint16_t sadb_address_exttype;

                   uint8_t sadb_address_proto;

                   uint8_t sadb_address_prefixlen;

                   uint16_t sadb_address_reserved;

           };

           /* sizeof(struct sadb_address) == 8 */

 

           /* 緊跟的是一些sockaddr結構格式的地址 */

 

       sockaddr結構應該系統實現的PF_KEY的sockaddr結構相一致。如果系統有sa_len

   消息中的sockaddrs也應有;如果沒有sa_len字段,sockaddrs也不應有。sockaddrs

   中的非地址信息,像AF_INET sockaddrs的sin_zero和AF_INET6 sockaddrs的sin6_

   flowinfo必須大於零。所有的消息的端口值(如sin_port和sin6_port)必須爲零,

   除了SADB_ACQUIRE消息,其發起者應填入相對應的TCP或UDP會話者的端口號。如果

   端口號非零,那麼sadb_address_proto字段,通常爲零,必須填入傳輸協議值。如

   果sadb_address_prefixlen非零,那麼地址有一個指定長度的前綴(常常用在KM訪

   問控制決策)。這些附加字段有利於密鑰關聯程序。

 

       在一個消息中,安全關聯的源和目的地址必須在同一個協議族,必須同時有或

   沒有。代理地址可以在不同的協議族,並且對於多數的安全協議,代表實際的包的

   發起者(例如:內部信息包的源地址在隧道中)。

 

       源地址必須是單播地址或者是非指定地址(如:INADDR_ANY)。目的地址可以

   是任一有效地址(單播、多播或廣播)。代理地址應是單播地址(這裏是試驗性的

   安全協議,代理可以不同於以上描述)。

 

 

2.3.4 密鑰擴展項

 

       密鑰擴展項說明了一個或多個與安全關聯有關的密鑰。由於安全原因,消息中

   的密鑰擴展項不是永遠存在。其格式如下:

 

           struct sadb_key {

                   uint16_t sadb_key_len;

                   uint16_t sadb_key_exttype;

                   uint16_t sadb_key_bits;

                   uint16_t sadb_key_reserved;

           };

           /* sizeof(struct sadb_key) == 8 */

 

           /* 緊跟的是密鑰 */

 

   sadb_key_bits   位數,有效的密鑰長度。如果爲零將導致錯誤。

 

       密鑰擴展項有兩種.認證密鑰(如:IPsec AH,OSPF MD5)和加密密鑰(如:

   IPsec ESP)。PF_KEY只處理符合格式的密鑰,不處理密鑰素材。例如,當使用

   ISAKMP/Oakley時,密鑰關聯進程總是負責在將Diffie-Hellman算法的計算結果通

   過PF_KEY發送至內核之前轉換成要求的格式。制定這項規則的原因是PF_KEY被設計

   成支持多種安全協議(不僅僅是IP安全)和多種密鑰管理機制,包括沒有“密鑰素

   材”概念的手工管理。一個清晰的不受協議約束的接口可以支持不同的操作系統和

   不同的安全協議。

 

       如果一個算法的密鑰定義了奇偶位(如:DES),那麼PF_KEY使用的密鑰也必須

   包含奇偶位。這意味着一個DES密鑰永遠是64位長。

 

       當一個安全協議只需要一個認證密鑰及?或一個加密密鑰時,使用適當的密鑰

   擴展進行完全格式轉換。當一個安全協議的同一個函數需要多個密鑰(如:3DES使

   用2或3個密鑰和非對稱算法),這兩個完全格式的密鑰必須按順序連在一起以便輸

   出包處理。在這種情況下,算法必須能夠根據提供的信息確定每個密鑰的長度。密

   鑰的總長度(當與使用的算法的知識相結合)通常提供足夠的信息去做出確定。

 

       密鑰始終通過PF_KEY接口按序傳遞以便輸出包的處理。對於輸入包的處理,密

   鑰的順序可能與PF_KEY接口使用的規範級連順序不同。具體實現負責使用正確的密

   鑰順序處理輸入和輸出包。

 

       例如,兩個單播地址的節點使用ESP、3個密鑰的3DES安全關聯通信。在發送節

   點的輸出SA和接收節點的輸入SA各自的加密密鑰擴展項中都依次包含key-A、key-B、

   key-C。輸出SA依次使用key-A、key-B、key-C加密,輸入SA依次使用key-C、key-B、

   key-C解密(注意:3DES實際上是加密-解密-加密)。3DES使用的規範的順序key-A、

   key-B、key-C已文檔化。規範的“加密”順序如同這個例子。[Sch96]

 

       密鑰數據位的有效位從高到低排列。例如:22位密鑰將佔3個字節,最低的兩

   位不包含密鑰素材,5個額外的填充字節用來64位邊界對齊。

 

       這裏有一個關於奇數位16進制密鑰的用戶接口問題,與PF_KEY不是直接有關。

   考慮以下16位數:

 

           0x123

 

       需要兩個字節儲存。如果沒有其它信息,不清楚究竟是存儲爲:

 

           01 23           或              12 30

 

       作者的看法是樣板(0x123 == 0x0123)是解釋這個多義性的最好方法。附加

   信息(如:寫成0x0123或0x1230,或者說明那只是12位數字)將解決這個問題。

 

 

2.3.5 身份擴展項

 

       身份擴展項包含了端點的身份特徵。這些信息被密鑰管理程序用來選擇協商中

   使用的身份證書。出於訪問控制的目的,內核也可以提供這些信息給網絡安全程序

   去鑑別遠端實體。如果這個擴展項不存在,密鑰管理必須以地址擴展項中的地址作

   爲安全關聯的唯一身份。其格式如下:

 

           struct sadb_ident {

                   uint16_t sadb_ident_len;

                   uint16_t sadb_ident_exttype;

                   uint16_t sadb_ident_type;

                   uint16_t sadb_ident_reserved;

                   uint64_t sadb_ident_id;

           };

           /* sizeof(struct sadb_ident) == 16 */

 

           /* 緊跟身份字符串,如果存在 */

 

   sadb_ident_type 緊跟的身份信息的類型。稍後詳述。

 

   sadb_ident_id   身份字符串不存在時使用的標識符。POSIX用戶標識符將使用這

                   個字段。稍後詳述。

 

       文本表示的身份信息包含在一個C字符串中緊跟在sadb_ident擴展項後。字符

   串的格式由sadb_ident_type的值確定,稍後詳述。

 

 

2.3.6 敏感度擴展項

 

       敏感度擴展包含安全關聯的安全標籤信息。如果這個擴展項不存在,就不能從

   安全關聯獲得敏感度關聯的數據;如果存在,數據包上的外在安全標籤的需求被回

   避。其格式如下:

 

           struct sadb_sens {

                   uint16_t sadb_sens_len;

                   uint16_t sadb_sens_exttype;

                   uint32_t sadb_sens_dpd;

                   uint8_t sadb_sens_sens_level;

                   uint8_t sadb_sens_sens_len;

                   uint8_t sadb_sens_integ_level;

                   uint8_t sadb_sens_integ_len;

                   uint32_t sadb_sens_reserved;

           };

           /* sizeof(struct sadb_sens) == 16 */

 

           /* 緊跟:

                   uint64_t sadb_sens_bitmap[sens_len];

                   uint64_t sadb_integ_bitmap[integ_len]; */

 

   sadb_sens_dpd   說明可以判讀等級和間隔位圖的保護進程。

   sadb_sens_sens_level

                   敏感度等級

   sadb_sens_sens_len

                   敏感度位圖的長度,64位字對齊。

   sadb_sens_integ_level

                   完整性等級

   sadb_sens_integ_len

                   完整性位圖的長度,64位字對齊。

 

       敏感度擴展設計來支持分離式或多級別安全系統的Bell-LaPadula[BL74]安全

   模型、Clark-Wilson[CW87]商業安全模型及/或Biba完整模型[Biba77]。這些正式

   的模型常用來實現各種各樣的安全策略。詳細的安全策略定義超出本文檔的討論範

   圍。每一個位圖必須64位邊界對齊。

 

 

2.3.7 提議擴展項

 

       提議擴展項包含了可選擇的算法參數,其格式如下:

 

           struct sadb_prop {

                   uint16_t sadb_prop_len;

                   uint16_t sadb_prop_exttype;

                   uint8_t sadb_prop_replay;

                   uint8_t sadb_prop_reserved[3];

           };

           /* sizeof(struct sadb_prop) == 8 */

 

           /* 緊跟:

              struct sadb_comb sadb_combs[(sadb_prop_len *

                  sizeof(uint64_t) - sizeof(struct sadb_prop)) /

                  sizeof(struct sadb_comb)]; */

 

       結構頭後是按優先排序的提議的參數聯合列表。如果一個聯合被選擇,那麼各

   字段值將存入相同定義的各字段中。

 

       注意:某些安全協議中的部分算法有IV長度變量,

 

   聯合的格式如下:

 

           struct sadb_comb {

                   uint8_t sadb_comb_auth;

                   uint8_t sadb_comb_encrypt;

                   uint16_t sadb_comb_flags;

                   uint16_t sadb_comb_auth_minbits;

                   uint16_t sadb_comb_auth_maxbits;

                   uint16_t sadb_comb_encrypt_minbits;

                   uint16_t sadb_comb_encrypt_maxbits;

                   uint32_t sadb_comb_reserved;

                   uint32_t sadb_comb_soft_allocations;

                   uint32_t sadb_comb_hard_allocations;

                   uint64_t sadb_comb_soft_bytes;

                   uint64_t sadb_comb_hard_bytes;

                   uint64_t sadb_comb_soft_addtime;

                   uint64_t sadb_comb_hard_addtime;

                   uint64_t sadb_comb_soft_usetime;

                   uint64_t sadb_comb_hard_usetime;

           };

 

           /* sizeof(struct sadb_comb) == 72 */

 

   sadb_comb_auth  如果聯合被接受,其值將存入sadb_sa_auth中。

 

   sadb_comb_encrypt

                   如果聯合被接受,其值將存入sadb_sa_encrypt中。

 

   sadb_comb_auth_minbits;

   sadb_comb_auth_maxbits;

                   最小和最大認證密鑰長度,位數。如果sadb_comb_auth爲零,這

                   兩個字段的值必須爲零;如果sadb_comb_auth非零,其值必須非

                   零。如果聯合被接受,KEY_AUTH的sadb_key_bits字段值將在兩

                   者之間。最小字段值不能大於最大字段值。

 

   sadb_comb_encrypt_minbits;

   sadb_comb_encrypt_maxbits;

                   最小和最大加密密鑰長度,位數。如果sadb_comb_encrypt爲零,

                   這兩個字段的值必須爲零;如果sadb_comb_encrypt非零,其值

                   必須非零。如果聯合被接受,KEY_ENCRYPT的sadb_key_bits字段

                   值將在兩者之間。最小字段值不能大於最大字段值。

 

   sadb_comb_soft_allocations

   sadb_comb_hard_allocations

                   如果聯合被接受,其值將分別存入SOFT和HARD生存期的

sadb_lifetime_allocations

                   中。

 

   sadb_comb_soft_bytes

   sadb_comb_hard_bytes

                   如果聯合被接受,其值將分別存入SOFT和HARD生存期的

sadb_lifetime_bytes

                   中。

 

   sadb_comb_soft_addtime

   sadb_comb_hard_addtime

                   如果聯合被接受,其值將分別存入SOFT和HARD生存期的

sadb_lifetime_addtime

                   中。

 

   sadb_comb_soft_usetime

   sadb_comb_hard_usetime

                   如果聯合被接受,其值將分別存入SOFT和HARD生存期的

sadb_lifetime_usetime

                   中。

 

       每一個聯合有一個認證和加密算法,也可以沒有,值爲零。聯合的標誌位同安

   全關聯擴展項的標誌位相同。最小和最大密鑰長度(位數)來自先驗的策略判斷,

   依賴於基本的算法特性。

 

 

2.3.8 支持算法擴展項

 

       支持算法擴展項包含系統所支持的算法列表,密鑰管理程序可以協商使用。可

   用的認證算法在SUPPORTED_AUTH擴展中列出,可用的加密算法在SUPPORTED_ENCRYPT

   擴展中列出。這些擴展的格式如下:

 

           struct sadb_supported {

                   uint16_t sadb_supported_len;

                   uint16_t sadb_supported_exttype;

                   uint32_t sadb_supported_reserved;

           };

           /* sizeof(struct sadb_supported) == 8 */

 

           /* 緊跟:

              struct sadb_alg sadb_algs[(sadb_supported_len *

                  sizeof(uint64_t) - sizeof(struct sadb_supported)) /

                  sizeof(struct sadb_alg)]; */

 

       擴展頭後是一個或多個算法描述,其格式如下:

 

           struct sadb_alg {

                   uint8_t sadb_alg_id;

                   uint8_t sadb_alg_ivlen;

                   uint16_t sadb_alg_minbits;

                   uint16_t sadb_alg_maxbits;

                   uint16_t sadb_alg_reserved;

           };

           /* sizeof(struct sadb_alg) == 8 */

 

   sadb_alg_id    算法標識。如果算法被選擇,其值將存在sadb_sa_auth和

sadb_sa_encrypt

                  中。

 

   sadb_alg_ivlen 初始化向量長度。如果IV不需要,其值必須爲零。

 

   sadb_alg_minbits

                  可接受的最小密鑰長度,位數。零無效。

 

   sadb_alg_maxbits

                  可接受的最大密鑰長度,位數。零無效。最小值不能大於最大值。

 

 

2.3.9 SPI範圍擴展項

 

       SADB_GETSPI消息需要一個可接受的SPI範圍,這項擴展完成這個功能。

 

           struct sadb_spirange {

                   uint16_t sadb_spirange_len;

                   uint16_t sadb_spirange_exttype;

                   uint32_t sadb_spirange_min;

                   uint32_t sadb_spirange_max;

                   uint32_t sadb_spirange_reserved;

           };

           /* sizeof(struct sadb_spirange) == 16 */

 

   sadb_spirange_min

                   可接受的最小SPI值。

 

   sadb_spirange_max

                   可接受的最大SPI值。最大值必須大於最小值。

 

 

2.4 消息格式的圖例

 

       下面展示PF_KEY消息的各字節安排,各選項也如此說明。

 

   基本消息頭如下:

 

     0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7

    +---------------+---------------+---------------+---------------+

    |  ...version   | sadb_msg_type | sadb_msg_errno| ...msg_satype |

    +---------------+---------------+---------------+---------------+

    |          sadb_msg_len         |       sadb_msg_reserved       |

    +---------------+---------------+---------------+---------------+

    |                         sadb_msg_seq                          |

    +---------------+---------------+---------------+---------------+

    |                         sadb_msg_pid                          |

    +---------------+---------------+---------------+---------------+

 

       基本消息頭後緊跟一個或多個擴展項,基於基本消息頭的不同的值。擴展項應

   按下面介紹的順序出現。

 

       一個擴展項不能重複出現。如果出現重複的情形,將會引起作者的注意。

 

   安全關聯擴展項

 

       0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7

       +---------------+---------------+---------------+---------------+

       |          sadb_sa_len          |        sadb_sa_exttype        |

       +---------------+---------------+---------------+---------------+

       |                          sadb_sa_spi                          |

       +---------------+---------------+---------------+---------------+

       |   ...replay   | sadb_sa_state | sadb_sa_auth  |sadb_sa_encrypt|

       +---------------+---------------+---------------+---------------+

       |                         sadb_sa_flags                         |

       +---------------+---------------+---------------+---------------+

 

   生存期擴展項

 

       +---------------+---------------+---------------+---------------+

       |         sadb_lifetime_len     |    sadb_lifetime_exttype      |

       +---------------+---------------+---------------+---------------+

       |                   sadb_lifetime_allocations                   |

       +---------------+---------------+---------------+---------------+

       |                    sadb_lifetime_bytes                        |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       |                    sadb_lifetime_addtime                      |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       |                    sadb_lifetime_usetime                      |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

 

   地址擴展項

 

       +---------------+---------------+---------------+---------------+

       |       sadb_address_len        |     sadb_address_exttype      |

       +---------------+---------------+---------------+---------------+

       | _address_proto| ..._prefixlen |     sadb_address_reserved     |

       +---------------+---------------+---------------+---------------+

       >     Some form of 64-bit aligned struct sockaddr goes here.    <

       >     一些64位對齊的sockaddr結構                                <

       +---------------+---------------+---------------+---------------+

 

   密鑰擴展項

 

       +---------------+---------------+---------------+---------------+

       |         sadb_key_len          |         sadb_key_exttype      |

       +---------------+---------------+---------------+---------------+

       |        sadb_key_bits          |        sadb_key_reserved      |

       +---------------+---------------+---------------+---------------+

       >    A key, padded to 64-bits, most significant bits to least.  >

       >    密鑰,填充至64位                                           >

       +---------------+---------------+---------------+---------------+

 

   身份擴展項

 

       +---------------+---------------+---------------+---------------+

       |        sadb_ident_len         |      sadb_ident_exttype       |

       +---------------+---------------+---------------+---------------+

       |        sadb_ident_type        |      sadb_ident_reserved      |

       +---------------+---------------+---------------+---------------+

       |                         sadb_ident_id                         |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       >  A null-terminated C-string which MUST be padded out for      >

       <  64-bit alignment.                                            <

       >  以空結束的C字符串,必須填充至64位對齊                        >

       +---------------+---------------+---------------+---------------+

 

   敏感度擴展項

 

       +---------------+---------------+---------------+---------------+

       |         sadb_sens_len         |      sadb_sens_exttype        |

       +---------------+---------------+---------------+---------------+

       |                         sadb_sens_dpd                         |

       +---------------+---------------+---------------+---------------+

       | ...sens_level | ...sens_len   |..._integ_level| ..integ_len   |

       +---------------+---------------+---------------+---------------+

       |                       sadb_sens_reserved                      |

       +---------------+---------------+---------------+---------------+

       >    The sensitivity bitmap, followed immediately by the        <

       <    integrity bitmap, each is an array of uint64_t.            >

       >    敏感度位圖,緊跟完整性位圖,64位排列                       <

       +---------------+---------------+---------------+---------------+

 

   提議擴展項

 

       +---------------+---------------+---------------+---------------+

       |         sadb_prop_len         |       sadb_prop_exttype       |

       +---------------+---------------+---------------+---------------+

       |...prop_replay |           sadb_prop_reserved                  |

       +---------------+---------------+---------------+---------------+

       >     One or more combinations, specified as follows...         <

       >     一個或多個聯合                                            <

       +---------------+---------------+---------------+---------------+

 

       聯合

       +---------------+---------------+---------------+---------------+

       |sadb_comb_auth |sadb_comb_encr |        sadb_comb_flags        |

       +---------------+---------------+---------------+---------------+

       |    sadb_comb_auth_minbits     |     sadb_comb_auth_maxbits    |

       +---------------+---------------+---------------+---------------+

       |   sadb_comb_encrypt_minbits   |    sadb_comb_encrypt_maxbits  |

       +---------------+---------------+---------------+---------------+

       |                       sadb_comb_reserved                      |

       +---------------+---------------+---------------+---------------+

       |                   sadb_comb_soft_allocations                  |

       +---------------+---------------+---------------+---------------+

       |                   sadb_comb_hard_allocations                  |

       +---------------+---------------+---------------+---------------+

       |                      sadb_comb_soft_bytes                     |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       |                      sadb_comb_hard_bytes                     |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       |                     sadb_comb_soft_addtime                    |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       |                     sadb_comb_hard_addtime                    |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       |                     sadb_comb_soft_usetime                    |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

       |                     sadb_comb_hard_usetime                    |

       |                           (64 bits)                           |

       +---------------+---------------+---------------+---------------+

 

   支持算法擴展項

 

       +---------------+---------------+---------------+---------------+

       |      sadb_supported_len       |     sadb_supported_exttype    |

       +---------------+---------------+---------------+---------------+

       |                    sadb_supported_reserved                    |

       +---------------+---------------+---------------+---------------+

 

      緊跟一個或多個算法描述

 

       +---------------+---------------+---------------+---------------+

       |  sadb_alg_id  | sadb_alg_ivlen|       sadb_alg_minbits        |

       +---------------+---------------+---------------+---------------+

       |        sadb_alg_maxbits       |       sadb_alg_reserved       |

       +---------------+---------------+---------------+---------------+

 

   SPI範圍擴展項

 

       +---------------+---------------+---------------+---------------+

       |       sadb_spirange_len       |     sadb_spirange_exttype     |

       +---------------+---------------+---------------+---------------+

       |                      sadb_spirange_min                        |

       +---------------+---------------+---------------+---------------+

       |                      sadb_spirange_max                        |

       +---------------+---------------+---------------+---------------+

       |                    sadb_spirange_reserved                     |

       +---------------+---------------+---------------+---------------+

 

 

3 符號名

 

       這一節定義了PF_KEY使用的各種符號和其含義。爲了可移植性,應用程序必須

   使用這些符號名。這裏定義的數字只是起說明作用,可以與其它系統不同,除非有

   其它明確規定。所有符合的執行必須保持符號名一致。

 

 

3.1 消息類型

 

       PF_KEY使用的消息類型,在文件<net/pfkeyv2.h>中定義。如下:

 

           #define SADB_RESERVED    0

           #define SADB_GETSPI      1

           #define SADB_UPDATE      2

           #define SADB_ADD         3

           #define SADB_DELETE      4

           #define SADB_GET         5

           #define SADB_ACQUIRE     6

           #define SADB_REGISTER    7

           #define SADB_EXPIRE      8

           #define SADB_FLUSH       9

 

           #define SADB_DUMP        10   /* 通常不用 */

 

           #define SADB_MAX         10

 

       每個消息的行爲包括最初的消息傳播(如:用戶層到內核)和隨後預期的動作。

   消息內容如下:

 

   <base, REQUIRED EXTENSION, REQ., (OPTIONAL EXT.,) (OPT)>

 

       安全關聯擴展項有時候只使用它的SPI字段,如果其它字段必須被忽略,就表

   示爲“SA(*)”。

 

       生存期擴展項表示爲一到三個字母跟在單詞“lifetime”後,H代表硬件、S

   代表軟件、C代表當前。

 

       地址擴展項表示爲一到三個字母跟在單詞“address”後,S代表源地址、D代

   標目的地址、P代表代理地址。

 

       注意:一些安全關聯類型不使用源地址作爲SA認證,而一些使用。這可導致一

             些不報告衝突的SA類型的EEXIT錯誤。希望程序作者充分了解安全關聯

             類型以便理解這些差別。

 

       密鑰擴展項表示爲一到兩各字母跟在單詞“key”後,A代表認證、E代表加密。

 

       身份擴展項表示爲一到兩各字母跟在單詞“identity”後,S代表源、D代表目

   的。

 

       當出現錯誤時,只返回基本消息頭。

 

       注意任何消息都可以返回任何標準錯誤。

 

       代表性的,它們既可以是一個消息的說明中詳細列出的一種錯誤,也可以是下

   列錯誤的一種:

 

           EINVAL  可以表示各種錯誤,包括SPI範圍不對。

           ENOMEM  內存不夠。

           ENOBUFS 緩存不夠。

           EMSGSIZ 消息長度錯誤。

 

 

3.1.1 SADB_GETSPI

 

       SADB_GETSPI消息允許一個進程根據安全關聯類型、源和目的地址獲得唯一的

   SPI值。它和緊跟的SADB_UPDATE消息是創建一個安全關聯的一種方法(SADB_ADD是

   另外一種方法)。進程在基本消息頭中指定類型,在地址擴展項中指定源和目的地

   址。如果SADB_GETSPI消息響應內核產生的SADB_ACQUIRE消息,那麼sadb_msg_seq

   必須和SADB_ACQUIRE消息一致。應用程序也可以指定SPI值,當內核使用SPI範圍擴

   展選定SPI值範圍。應用程序設置相同的最高和最低值可以指定單一的通過驗證的

 

   SPI值。允許指定範圍是因爲內核能夠根據已使用的SPI值分配SPI值。內核將分配

   的SPI值保存在安全關聯擴展的spi字段,然後返回同一個消息。分配的SPI(和目

   的地址)指出一個LARVAL期的安全關聯。隨後的SADB_UPDATE消息利用請求的SPI值

   增加整個安全關聯項目。

 

       如果使用SADB_GETSPI消息建立的安全關聯沒有使用SADB_UPDATE消息更新,應

   該定期自動刪除。這樣保存的SA不會混亂。

 

     SADB_GETSPI消息機制:

 

        用戶進程發送SADB_GETSPI消息到內核。

 

        <base, address, SPI range>

 

        內核返回SADB_GETSPI消息給所有的監聽進程。

 

        <base, SA(*), address(SD)>

 

     錯誤:

 

        EEXIST  請求的SPI值或SPI範圍值不可用或已經使用。

 

 

3.1.2 SADB_UPDATE

 

       SADB_UPDATE消息允許一個進程更新已存在的安全關聯的信息。由於SADB_GETSPI

   不允許設置一些參數,所以SADB_UPDATE消息需要完全構建由SADB_GETSPI建立的狀

   態爲SADB_SASTATE_LARVAL的安全關聯。SADB_UPDATE消息的格式由一個基本消息頭、

   安全關聯頭和幾個可選的擴展頭組成。內核根據消息中指定的類型、SPI、源和目的

   地址搜索相同的安全關聯並用消息中的內容更新。

 

       內核可以不接受SADB_UPDATE消息,除非消息由建立安全關聯的套接字發出。

   這樣可以避免意外修改正在使用的安全關聯。惡意的可信程序仍然可以發出SADB_FLUSH

   或SADB_DELETE消息,但是安全關聯的刪除可以很容易的發現,而不像意外出現的

   錯誤SADB_UPDATE消息。相反的意見是當用戶層的密鑰管理程序出現錯誤並重啓,

   新的實例和安全關聯建立者不會有相同的套接字。

 

       內核必須在更新數據庫中的SA之前對SADB_UPDATE消息提交的有效值做安全檢

   查,如果任何值無效必須返回EINVAL錯誤。例如:應檢查DES密鑰的奇偶位、密鑰長

   度、已知的指定算法的弱密鑰、已知的指定算法不兼容的標誌或參數。

 

       只有狀態爲SADB_SASTATE_MATURE的SA可以接受SADB_UPDATE消息。如果SA的狀

   態爲SADB_SASTATE_LARVAL,那麼可以修改除了源地址、目的地址和SPI以外的值。

   如果SA的狀態爲SADB_SASTATE_DEAD,任何更新嘗試必將返回EINVAL錯誤。對已確

   定的密鑰或算法信息進行修改而不修改SPI是無效的,那樣與其修改一個已存在的SA

   不如請求建立一個新的SA。一旦SA的密鑰和算法信息商定,那麼地址和身份信息也

   已確定。所以,如果狀態爲SADB_SASTATE_MATURE或DYING的SA,只有SA頭的

sadb_sa_state

   和生存期(硬件、軟件和當前)可以修改,其它修改必將返回EINVAL錯誤。

 

     SADB_UPDATE消息機制:

 

        Send an SADB_UPDATE message from a user process to the kernel.

        用戶進程發送SADB_UPDATE消息到內核。

 

        <base, SA, (lifetime(HSC),) address(SD), (address(P),)

          key(AE), (identity(SD),) (sensitivity)>

 

        內核返回SADB_UPDATE消息給所有的監聽進程。

 

        <base, SA, (lifetime(HSC),) address(SD), (address(P),)

          (identity(SD),) (sensitivity)>

 

       密鑰素材將不在從內核到監聽套接字的消息中返回,因爲監聽者不一定有特權。

 

     錯誤:

 

         ESRCH   要更新的安全關聯沒有找到。

         EINVAL  其它可能錯誤,如果參數健全檢查(如密鑰)錯誤返回此值。

         EACCES  權限不夠。發送SADB_UPDATE消息的套接字不是建立者。

 

 

3.1.3 SADB_ADD

 

       SADB_ADD消息除了不需要預先呼叫SADB_GETSPI消息,其它與SADB_UPDATE消息

   相同。SADB_ADD消息用於手工密鑰管理程序,在其它情況下唯一的SPI可以立即知

   道。

 

       SADB_ADD消息也用於協商結束後一對安全關聯中的第二個安全關聯的增加,SPI

   值由對端機器決定。sadb_msg_seq必須設置成內核產生的SADB_ACQUIRE消息中的值,

   這樣兩個安全關聯綁定同一個ACQUIRE請求。

 

       內核必須在增加SA至數據庫之前對所有SADB_ADD消息中提交的字段進行健全檢

   查,如果任何值無效,必須返回EINVAL錯誤。

 

       只有狀態爲SADB_SASTATE_MATURE的SA可以在SADB_ADD消息中提交。狀態爲

   SADB_SASTATE_LARVAL的SA由SADB_GETSPI建立,並且在DYING或SADB_SASTATE_DEAD

   狀態下增加新的SA是不明智的。因此,所有提交的SA的sadb_sa_state字段值必須

   是SADB_SASTATE_MATURE,否則內核必須返回錯誤。

 

     SADB_ADD消息機制如下:

 

        Send an SADB_ADD message from a user process to the kernel.

        用戶進程發送SADB_ADD消息到內核。

 

        <base, SA, (lifetime(HS),) address(SD), (address(P),)

          key(AE), (identity(SD),) (sensitivity)>

 

        內核返回SADB_ADD消息給所有的監聽進程。

 

        <base, SA, (lifetime(HS),) address(SD), (identity(SD),)

          (sensitivity)>

 

       密鑰素材將不在從內核到監聽套接字的消息中返回,因爲監聽者不一定有特權。

 

     錯誤:

 

        EEXIST  要增加的安全關聯已經存在。

        EINVAL  其它可能錯誤,如果參數健全檢查(如密鑰)錯誤返回此值。

 

 

3.1.4 SADB_DELETE

 

       SADB_DELETE消息導致內核從密鑰表中刪除安全關聯。刪除消息包含基本消息

   頭和安全關聯擴展、源和目的地址擴展。內核刪除與消息中的類型、SPI、源和目

   的地址相匹配的安全關聯。

 

     SADB_DELETE消息機制如下:

 

        用戶進程發送SADB_DELETE消息到內核。

 

        <base, SA(*), address(SD)>

 

        內核返回SADB_DELETE消息給所有的監聽進程。

 

        <base, SA(*), address(SD)>

 

 

3.1.5 SADB_GET

 

       SADB_GET允許一個進程從內核密鑰表中獲得一個安全關聯的拷貝。GET消息由

   基本消息頭和有關的擴展項組成。內核將返回與消息中的類型、SPI、源和目的地

   址相匹配的安全關聯。

 

      SADB_GET消息機制如下:

 

         用戶進程發送SADB_GET消息到內核。

 

         <base, SA(*), address(SD)>

 

         內核返回SADB_GET消息給發送者的套接字。

 

         <base, SA, (lifetime(HSC),) address(SD), (address(P),) key(AE),

           (identity(SD),) (sensitivity)>

 

     錯誤:

 

         ESRCH   沒有找到匹配的安全關聯

 

 

3.1.6 SADB_ACQUIRE

 

       SADB_ACQUIRE消息典型的應用是由內核發送至已登記(見SADB_REGISTER消息)

   的密鑰套接字監聽者。SADB_ACQUIRE消息可以被應用層用戶的安全關聯發送(像使

   用OSPF安全的OSPFv2實現)。SADB_ACQUIRE消息由基本消息頭連同地址擴展、可選

   的身份擴展和提議擴展組成。提議包含想用的算法列表,如果算法在基本消息頭中

   不可用。基本消息頭中的字段和緊跟的安全關聯數據指出監聽進程企圖獲得的安全

   關聯的特性。如果消息從內核發出(sadb_msg_pid爲0),隨後的SADB_GETSPI消息

   和SADB_UPDATE消息必須使用sadb_msg_seq的值,或者隨後的SADB_ADD消息用來綁

   定一個安全關聯的請求。這樣可以避免需要唯一安全關聯的兩個IP主機之間的兩個

   TCP連接的競爭,可以避免一個使用另一個安全關聯。監聽進程應忽略sadb_msg_errno

   和sadb_msg_state字段。

 

       當內核密鑰表中沒有輸出包需要的可用的安全關聯時觸發SADB_ACQUIRE消息。

   如果包可以被多個算法或可選聯合充分保護,SADB_ACQUIRE消息必須按序優先使

   用提議擴展中的選項。

 

       SADB_ACQUIRE消息有三種機制。第一種是內核需要一個安全關聯(如IPsec)。

 

     內核發送SADB_ACQUIRE消息至已註冊的套接字。

 

        <base, address(SD), (address(P)), (identity(SD),) (sensitivity,)

          proposal>

 

        注意:  地址(源和目的)擴展的端口字段必須填入需要密鑰會話的端口號。

 

       第二種:由於某些原因,密鑰關聯失敗,可以發送一個帶有非零錯誤號與最初

   的ACQUIRE消息相同sadb_msg_seq值的ACQUIRE消息。

 

        發送SADB_ACQUIRE指出密鑰管理失敗。

 

        <base>

 

       第三種:安全關聯的應用層用戶(如:OSPFv2或RIPv2守護進程)需要一個安

   全關聯。

 

        用戶進程發送SADB_ACQUIRE消息至內核。

 

        <base, address(SD), (address(P),) (identity(SD),) (sensitivity,)

          proposal>

 

        內核返回一個SADB_ACQUIRE消息至已註冊的套接字。

 

        <base, address(SD), (address(P),) (identity(SD),) (sensitivity,)

          proposal>

 

        應用層用戶等待特殊類型SADB_UPDATE或SADB_ADD消息後,使用SADB_GET消息

        可以獲得使用安全關聯。

 

   錯誤:

 

       EINVAL  無效的ACQUIRE請求。

       EPROTONOSUPPORT

               沒有密鑰管理程序註冊到密鑰引擎能夠獲得請求的SA類型,於是請求

               的SA不能被獲得。

 

 

3.1.7 SADB_REGISTER

 

       SADB_REGISTER消息允許程序註冊自己密鑰套接字,從而能獲得新的安全關聯。

   SADB_REGISTER消息允許套接字接收SADB_ACQUIRE消息,對於sadb_msg_satype中指

   定類型的安全關聯。程序指定安全關聯的類型可以從內核中註冊消息的類型字段獲

   得。如果應用程序可以獲得多個類型,必須分別註冊每個類型。密鑰管理程序可以

   註冊內核未知的類型,因爲應用層用戶可以識別(如OSPFv2安全)。

 

       SADB_REGISTER消息的應答包含一個支持算法擴展,列出支持的算法,一個佔一

   個字節。這樣可以使密鑰管理程序知道內核支持的算法。

 

       在算法可以動態裝載和卸載的環境,可以產生異步的SADB_REGISTER應答。支

   持的算法列表必須完全列出,這樣應用程序能夠註釋和添加。

 

     SADB_REGISTER消息機制如下:

 

        用戶進程發送SADB_REGISTER消息至內核。

 

        <base>

 

        內核返回SADB_REGISTER消息至註冊的套接字,在支持算法字段指出內核支持

        的算法。

 

        <base, supported>

 

        注意: 這個消息可以異步到達,當算法可以裝載和卸載的動態聯接內核。

 

 

3.1.8 SADB_EXPIRE

 

       操作系統內核負責跟蹤在內核中執行的安全協議的SA有效期。如果內核中執行

   的安全協議的一個安全關聯的軟件限制或硬件限制期滿,內核必須發送SADB_EXPIRE

   消息給所有的密鑰套接字監聽者。如果用戶層安全協議的一個安全關聯的軟件限制

   或硬件限制期滿,用戶層協議應發送SADB_EXPIRE消息。

 

       消息由基本消息頭、源和目的地址、可能存在的內部套接字地址和可能存在的

   一個或兩個間隔位圖。

 

       SADB_EXPIRE消息的生存期擴展指出哪一個到期。如果包含HARD生存期擴展,

   說明HARD生存期期滿,這意味着安全關聯可能已從SADB中刪除。如果包含SOFT生存

   期擴展,說明SOFT生存期期滿。CURRENT生存期擴展將指出當前狀態,並且對照HARD

   或SOFT生存期將指出哪一個到達。HARD生存期必須優先於SOFT生存期,如果HARD和

   SOFT生存期相同,消息中將包含HARD生存期。如果HARD生存期比SOFT生存期短,SOFT

   生存期將永遠不會到期。

 

     SADB_EXPIRE消息機制如下:

 

        當安全關聯的軟件限制期滿,內核發送SADB_EXPIRE消息至所有的監聽者。

 

           <base, SA, lifetime(C and one of HS), address(SD)>

 

       注意,SADB_EXPIRE消息只能由內核發送至密鑰管理守護進程。它是一個單向

   的通報消息,沒有應答。

 

 

3.1.9 SADB_FLUSH

 

       SADB_FLUSH消息導致內核刪除密鑰表中確定的sadb_msg_satype的所有的條目。

   消息中只有基本消息頭。如果sadb_msg_satype包含指定值,只有改類型的安全關

   聯被刪除;如果值爲SADB_SATYPE_UNSPEC,所有的安全關聯被刪除。

 

     SADB_FLUSH消息機制如下:

 

           用戶進程發送SADB_FLUSH消息至內核。

 

           <base>

 

           內核返回SADB_FLUSH消息至所有的套接字監聽者。

 

           <base>

 

           應答消息只有在實際的安全關聯刷新執行後發送。

 

 

3.1.10 SADB_DUMP

 

       SADB_DUMP消息導致內核輸出系統的整個密鑰表至發出請求的密鑰套接字。像

   SADB_FLUSH消息,如果消息中的sadb_msg_satype值指定,只輸出類型匹配的安全

   關聯;如果值爲SADB_SATYPE_UNSPEC,所有的安全關聯被輸出。每個安全關聯在自

   己的SADB_DUMP消息中返回。SADB_DUMP消息的sadb_seq爲零指輸出結束。這個消息

   只是用於調試,不必在程序中使用。

 

       在將來的PF_KEY版本中SADB_DUMP消息可能不支持。密鑰管理程序的基本操作

   不能依賴於這個消息。

 

     SADB_DUMP消息機制如下:

 

           用戶進程發送SADB_DUMP消息至內核。

 

           <base>

 

           幾個SADB_DUMP消息將從內核返回至發送者的套接字。

 

           <base, SA, (lifetime (HSC),) address(SD), (address(P),)

             key(AE), (identity(SD),) (sensitivity)>

 

 

3.2 安全關聯標誌

 

       安全關聯的標誌是一個按位操作的字段。這些標誌也出現在提議擴展的間隔中。

   爲了程序的可移植性,下面定義的相關符號應使用。

 

     #define SADB_SAFLAGS_PFS 1    /* 完美向前保密 */

 

       SADB_SAFLAGS_PFS標誌指出一個安全關聯用它的密鑰進行完全向前保密。(也

   就是說,任何特定會話密鑰不能被以前的會話密鑰破解或某個萬能密鑰確定)。

 

 

3.3 安全關聯狀態

 

       安全關聯狀態是一個描述狀態的整數指。如下:

 

     #define SADB_SASTATE_LARVAL   0

     #define SADB_SASTATE_MATURE   1

     #define SADB_SASTATE_DYING    2

     #define SADB_SASTATE_DEAD     3

 

     #define SADB_SASTATE_MAX      3

 

       狀態爲SADB_SASTATE_LARVAL的安全關聯由SADB_GETSPI消息建立。狀態爲

   SADB_SASTATE_MATURE的安全關聯由SADB_UPDATE消息更新或由SADB_ADD消息添加。

   狀態爲SADB_SASTATE_DYING的安全關聯指其軟件生存期期滿。狀態爲SADB_SASTATE_DEAD

   的安全關聯指其硬件生存期期滿,但是還未被系統碎片收集。如果一個用戶的安全

   關聯擴展其正常週期(如:OSPF安全),必須只設置安全關聯的軟件生存期。

 

 

3.4 安全關聯類型

 

 

       安全關聯類型說明了消息中安全關聯的類型。類型的符號名總是相同,甚至在

   不同的實現中。爲了不同實現間的移植,程序應使用這些在<net/pfkeyv2.h>中定

   義的符號名。

 

     #define SADB_SATYPE_UNSPEC        0

 

     #define SADB_SATYPE_AH            2  /* RFC-1826 */

     #define SADB_SATYPE_ESP           3  /* RFC-1827 */

 

     #define SADB_SATYPE_RSVP          5  /* RSVP認證 */

     #define SADB_SATYPE_OSPFV2        6  /* OSPFv2認證 */

     #define SADB_SATYPE_RIPV2         7  /* RIPv2認證 */

     #define SADB_SATYPE_MIP           8  /* 移動IP認證 */

 

     #define SADB_SATYPE_MAX           8

 

   SADB_SATYPE_UNSPEC 意味着安全關聯無指定類型。這個類型從未被PF_KEY安全關

                      聯使用。

 

   SADB_SATYPE_AH 用於IP認證頭[Atk95b]。

 

   SADB_SATYPE_ESP 用於IP安全載荷[Atk95c]。

 

   SADB_SATYPE_RSVP 用於RSVP完整對象。

 

   SADB_SATYPE_OSPFV2 用於OSPFv2加密認證[Moy98]。

 

   SADB_SATYPE_RIPV2 用於RIPv2加密認證[BA97]。

 

   SADB_SATYPE_MIP 用於移動IP的認證擴展[Per97]

 

   SADB_SATYPE_MAX 永遠設置成最大的有效值。

 

 

3.5 算法類型

 

       算法類型與上面定義的安全關聯類型上下關聯。其值可能在不同實現中有區別,

   但是符號名必須相同。爲了不同實現間的移植,程序應使用這些符號名。

 

       下面定義的一些算法類型可能是不標準的或者將來可能不支持。想得到一個分

   配的符號名,聯繫作者。

 

     下面的符號在<net/pfkeyv2.h>中定義。

 

           /* 認證算法 */

           #define SADB_AALG_NONE          0

           #define SADB_AALG_MD5HMAC       2

           #define SADB_AALG_SHA1HMAC      3

           #define SADB_AALG_MAX           3

 

           /* 加密算法 */

           #define SADB_EALG_NONE          0

           #define SADB_EALG_DESCBC        2

           #define SADB_EALG_3DESCBC       3

           #define SADB_EALG_NULL          11

           #define SADB_EALG_MAX           11

 

       SADB_AALG_MD5_HMAC算法在[MG98a]中定義。SADB_AALG_SHA1HMAC算法在[MG98b]

   定義。SADB_EALG_DESCBC算法在[MD98]中定義。SADB_EALG_NULL指空加密算法,在

   [GK98]中定義。SADB_EALG_NONE在任何安全關聯中不使用,除非沒有加密算法(如

   IPsec認證)。

 

 

3.6 擴展頭值

 

       簡短的擴展頭值摘要表:

 

           #define SADB_EXT_RESERVED          0

           #define SADB_EXT_SA                1

           #define SADB_EXT_LIFETIME_CURRENT  2

           #define SADB_EXT_LIFETIME_HARD     3

           #define SADB_EXT_LIFETIME_SOFT     4

           #define SADB_EXT_ADDRESS_SRC       5

           #define SADB_EXT_ADDRESS_DST       6

           #define SADB_EXT_ADDRESS_PROXY     7

           #define SADB_EXT_KEY_AUTH          8

           #define SADB_EXT_KEY_ENCRYPT       9

           #define SADB_EXT_IDENTITY_SRC      10

           #define SADB_EXT_IDENTITY_DST      11

           #define SADB_EXT_SENSITIVITY       12

           #define SADB_EXT_PROPOSAL          13

           #define SADB_EXT_SUPPORTED_AUTH    14

           #define SADB_EXT_SUPPORTED_ENCRYPT 15

           #define SADB_EXT_SPIRANGE          16

 

           #define SADB_EXT_MAX               16

 

 

3.7 身份擴展值

 

       每一個身份有確定的類型。

 

           #define SADB_IDENTTYPE_RESERVED  0

           #define SADB_IDENTTYPE_PREFIX    1

           #define SADB_IDENTTYPE_FQDN      2

           #define SADB_IDENTTYPE_USERFQDN  3

 

           #define SADB_IDENTTYPE_MAX       3

 

       PREFIX身份字符串由網絡地址斜線和前綴長度組成。網絡地址是與協議族相匹

   配的可打印的數字格式。前綴長度是一個大於等於零並小於網絡地址位數的十進制

   數字,指出網絡地址的有效位數;若網絡地址的所有位無意義必須設置爲零。注意,

   具體實現必須將可打印的地址解析成二進制格式用於比較,因爲在很多協議族中同

   一地址可以表示多種格式的可打印字符串(例如,一些允許以零開始,一些則不是)。

   PREFIX身份的例子:“199.33.248.64/27”和“3ffe::1/128”。如果源和目的地

   址是PREFIX身份,用於SA(分別)的源和目的地址必須在前綴範圍內。對於這個身

   份類型sadb_ident_id的值爲零。

 

       FQDN身份字符串包含正式域名。FQDN身份的例子:“ministry-of-truth.inner.net”。

   對於這個身份類型sadb_ident_id的值爲零。

 

       UserFQDN身份字符串由因特網標準的電子郵件格式的文本字符串組成。格式爲:

   用戶名,中間是“@”字符,接着是正式域名。它指定了用戶名和與之相關的FQDN。

   這裏沒必要指定一個SMTP或其它電子郵件應用的有效郵箱。這個身份有利於面向用

   戶的協議支持的密鑰管理。這是一個滿意的格式,因爲安全的DNS擴展可以用於分

   發籤名的公鑰,通過用合適的MB DNS檔案記錄關聯的KEY和SIG。UserFQDN身份的例

   子:“[email protected]”。sadb_ident_id字段包含POSIX用戶

   標識,缺省是身份字符串,這樣用戶層程序能夠使用getpwuid{,_r}()獲得文本的

   用戶註冊ID。如果存在,在sadb_ident_id field字段應返回匹配的數字值;如果

   不匹配,字符串應覆蓋數字值。

 

 

3.8 敏感度擴展值

 

       在敏感度擴展中目前定義的字段只有sadb_sens_dpd,表示了數據保護域。敏

   感度擴展的其它數據不基於sadb_sens_dpd值。

 

       DP/DOI的定義與IP安全的DOI規範[Pip98]中的“Labeled Domain Identifier

   Value”相同。如同規範中的註釋:0x80000000和0xffffffff之間的值保留給私人

   使用,0x00000001到0x7fffffff分配給IANA。全零的DP/DOI值永遠表示:沒有DP/DOI

   在使用。

 

 

3.9 提議擴展值

 

       這些已在算法類型和安全關聯標誌中提及。

 

 

4 發展趨勢

 

       當前說明敏感度和完整標註的規範相信足夠全面,如果出現使用當前規範不能

   工作的情況,將在PF_KEY的未來版本中改正。

 

       同樣地,PF_KEY可能需要擴展以便適用於未來其它種類地安全關聯。像這樣地

   擴展將是向後兼容的方式。

 

       當獲得更多的證書管理經驗後,可能身份擴展將允許證書身份。

 

 

5. 實例

 

       下面的例子圖解PF_KEY怎樣使用。第一個例子是一個IP安全例子,安全關聯的

   用戶在操作系統內核內部。第二個例子是一個OSPF安全例子,說明用戶層用戶的安

   全關聯。第三個例子包含頭兩個例子沒有提及的情況。真實系統可以符合這些例子

   的一種,或者一部分。這些例子完全是說明性的,不想要求詳細的實現方法。

 

 

5.1 簡單的IP安全例子

 

                     +---------------+    +-------------+

                     |   密鑰管理    |    |    應用     |

                     |   守護進程    |    |    程序     |

                     +---------------+    +-------------+

                       |           |     /

                       |           |    /

                       |           |    |              應用程序

               ======[PF_KEY]====[PF_INET]==========================

                       |           |    |              系統內核

               +------------+   +-----------------+

               |  密鑰引擎  |   |    TCP/IP       |

               |   或者     |   |    包括         |

               |   SADB     |---|    IPsec        |

               +------------+   |                 |

                                +-----------------+

 

       當密鑰管理守護進程(KMd)開始,必須告訴PF_KEY將要接收消息用於IPsec的

   兩個服務,AH和ESP。通過發送兩個SADB_REGISTER消息完成這些。

 

     KMd->Kernel:         SADB_REGISTER for ESP

     Kernel->Registered:  SADB_REGISTER for ESP, Supported Algorithms*

     KMd->Kernel:         SADB_REGISTER for AH

     Kernel->Registered:  SADB_REGISTER for AH, Supported Algorithms

 

       每一個REGISTER消息將導致一個應答給所有分別註冊到ESP和AH的PF_KEY套接

   字(包括請求發送者)。

 

       假設IPsec當前可使用的安全關聯不存在,認爲一個網絡程序開始傳送數據(

   例如一個TCP的SYN)。因爲策略關係,或者程序的要求,內核IPsec模塊需要一個

   AH安全關聯用於這些數據。由於不存在,產生以下消息:

 

     Kernel->Registered:  SADB_ACQUIRE for AH, addrs, ID, sens,

                          proposals

 

       KMd讀取ACQUIRE消息,尤其是sadb_msg_seq值。在開始協商前,發送含有相同

   sadb_msg_seq值的SADB_GETSPI消息。內核返回GETSPI的結果給所有的監聽套接字。

 

     KMd->Kernel:         SADB_GETSPI for AH, addr, SPI range

     Kernel->All:         SADB_GETSPI for AH, assoc, addrs

 

       KMd可以完成第二個GETSPI操作,如果它需要雙向的IPsec SPI值,KMd得到SPI

   後,開始協商。在派生出密鑰素材,並協商其它參數後,發送一個(或多個)包含

   同一sadb_msg_seq值的SADB_UPDATE消息。

 

       如果在協商中KMd出現任何錯誤,將發送:

 

     KMd->Kernel:         SADB_ACQUIRE for AH, assoc (with an error)

     Kernel->All:         SADB_ACQUIRE for AH, assoc (same error)

 

       如果成功,將發送:

 

     KMd->Kernel:         SADB_UPDATE for AH, assoc, addrs, keys,

                          <etc.>

     Kernel->All:         SADB_UPDATE for AH, assoc, addrs, <etc.>

 

       UPDATE的結果(去掉實際的密鑰)發送給所有的監聽套接字。如果只有SPI值

   在本地確定,其它SPI(由於IPsec的SA是單向的)必須用SADB_ADD增加。

 

     KMd->Kernel:         SADB_ADD for AH, assoc, addrs, keys, <etc.>

     Kernel->All:         SADB_ADD for AH, assoc, addrs, <etc.>

 

       如果擴展項中有生存期擴展,當生存期中的一項期滿,將收到SADB_EXPIRE消

   息。

 

     Kernel->All:         SADB_EXPIRE for AH, assoc, addrs,

                          Hard or Soft, Current, <etc.>

 

       KMd可以使用以這個消息爲線索開始協商,或者,如果對策略有發言權,發送

   帶生存期擴展的SADB_UPDATE消息。

 

 

5.2 代理IP安全例子

 

       很多人對在“代理”或“防火牆”結構中使用IP安全感興趣,那樣中間系統可

   以爲“內部”主機提供安全服務。在這些環境下,中間的系統可以使用PF_KEY通過

   密鑰管理程序通信就像實際的終端。在這種情況下,PF_KEY的消息機制同前面的例

   子相同,但是地址信息稍微不同。

 

     考慮這種情況:

 

                     A ========= B --------- C

 

     說明:

               A           "outside" host that implements IPsec

               A           執行IPsec的“外部”主機

               B           "firewall" that implements IPsec

               B           執行IPsec的“防火牆”

               C           "inside" host that does not implement IPsec

               C           沒有執行IPsec的“內部”主機

 

               ===         IP_{A<->B} ESP [ IP_{A<->C} ULP ]

               ---         IP_{A<->C} ULP

 

 

       A是一個單一系統,想要和“內部”系統C通信。B是一個“防火牆”在C和外部

   世界之間,爲C的利益做ESP和隧道保護。A發現它需要通過B發送話務利用這裏沒有

   描述的方法(使用DNS的KX記錄可能是一種方法)。

 

       當信息包由左至右傳輸,A和B需要的IPsec安全關聯:

 

           SA類型爲ESP隧道模式

           支配A的源身份(例如:A的地址)

           支配B的目的身份(例如:B的地址)

           源地址A

           目的地址B

 

       當信息包由右至左傳輸,A和B需要的IPsec安全關聯:

 

           SA類型爲ESP隧道模式

           支配C的源身份

           支配A的目的身份

           源地址B

           目的地址A

           代理地址C

 

       對於第二個SA(信息包由C到A),節點A必須檢驗SA使用的源身份控制的內部

   源地址。否則,攻擊者可以用任意的源身份僞造信息包,並代替IPsec保護的原包。

 

     現在考慮稍微複雜的情況:

 

               A_1 --|                  |-- D_1

                     |--- B ====== C ---|

               A_2 --|                  |-- D_2

 

     說明:

               A_n     "inside" host on net 1 that does not do IPsec.

               A_n     子網1的“內部”主機,沒有IPsec

               B       "firewall" for net 1 that supports IPsec.

               B       子網1的“防火牆”,支持IPsec

               C       "firewall" for net 2 that supports IPsec.

               C       子網2的“防火牆”,支持IPsec

               D_n     "inside" host on net 2 that does not do IPsec.

               D_n     子網2的“內部”主機,沒有IPsec

               ===     IP_{B<->C} ESP [ IP_{A<->C} ULP ]

               ---     IP_{A<->C} ULP

 

           當A_1發送包至D_1,B和C需要的SA:

 

                   SA類型爲ESP

                   支配A_1的源身份

                   支配C的目的身份

                   源地址B

                   目的地址C

                   代理地址A_1

 

           當D_1發送包至A_1,C和B需要的SA:

 

                   SA類型爲ESP隧道模式

                   支配D_1的源身份

                   支配B的目的身份

                   源地址C

                   目的地址B

                   代理地址D_1

 

       注意,A_2和D_2可以分別替換A_1和D_1;SA和一對特定的終端或羣組相結合是

   B及/或C上的一個策略決議,並且對於密鑰管理不是必需的功能。出於同樣的原因,

   在這種情況下依靠內部IP地址的源身份檢查必須履行。

 

       關於在複雜環境下使用IP安全的更多的詳細的討論,請看[Atk97]。

 

     注意:身份支配的概念可能不熟悉。假設H代表節點;Hn代表H的正式域名;Ha代

     表H的地址;Hs代表包含Ha的IP子網;Hd代表H的上一級節點的正式域名;M代表

     UserFQDN身份,它的後面是Hn或Ha。

 

         在上面的例子中,無論M、Hn、Ha、Hs和Hd被認爲支配H。Hs支配地址在IP地

     址範圍內的任一節點。Hd支配域名在其正式域名下面的任一節點。

 

 

5.3 OSPF安全例子

 

           +---------------+    +-------------+

           |   密鑰管理    |    |    OSPF     |

           |   守護進程    |    |  守護進程   |

           +---------------+    +-------------+

             |           |     /    /        |

             |    /------|----+    /         |

             |   /       |    +---+          |           應用程序

     ======[PF_KEY]====[PF_INET]===========[PF_ROUTE]================

             |           |    |              |           系統內核

     +------------+   +-----------------+  +---------+

     |  密鑰引擎  |   |    TCP/IP       |  |         |

     |  或者      |---|    包括         |--| 路由表  |

     |  SADB      |   |    IPsec        |  |         |

     +------------+   |                 |  +---------+

                      +-----------------+

 

       像前面的例子中,KMd通過PF_KEY註冊到密鑰引擎。儘管如此,安全關聯的使

   用者在用戶層,PF_KEY和密鑰引擎的執行能夠儲存SA和轉發消息。

 

       當OSPF進程需要同對端進行安全通信,就發出SADB_GET消息並得到合適的安全

   關聯:

 

     OSPFd->Kernel:       SADB_GET of OSPF, assoc, addrs

     Kernel->OSPFd:       SADB_GET of OSPF, assoc, addrs, keys, <etc.>

 

       如果GET操作失敗,OSPFd可能需要獲取新的安全關聯。這個交互過程如下:

 

     OSPFd->Kernel:       SADB_ACQUIRE of OSPF, addrs, <ID, sens,>

                          proposal

     Kernel->Registered:  SADB_ACQUIRE of OSPF, <same as sent message>

 

       KMd理解這些消息並完成操作與前面的例子相似。一個區別:當UPDATE消息返

   回,OSPFd將執行一個GET操作去獲取更新SA的所有參數。

 

 

5.4 其它

 

       一些消息只有在系統維護程序中用到,如調試或審計。在系統混亂時,像發現

   危及安全,將發送指定類型或所有SA類型的SADB_FLUSH消息。

 

     Program->Kernel:     SADB_FLUSH for ALL

     <Kernel then flushes all internal SAs>

     Kernel->All:         SADB_FLUSH for ALL

 

       一些SA可能需要刪除,可能被KMd,也可能被系統維護程序。

 

     Program->Kernel:     SADB_DELETE for AH, association, addrs

     Kernel->All:         SADB_DELETE for AH, association, addrs

 

       SADB_DUMP消息的普通操作被放棄,然而,出於調試目的,它還是很有用的。

   DUMP的輸出應迅速讀取,以免套接字緩衝溢出。

 

     Program->Kernel:     SADB_DUMP for ESP

     Kernel->Program:     SADB_DUMP for ESP, association, <all fields>

     Kernel->Program:     SADB_DUMP for ESP, association, <all fields>

     Kernel->Program:     SADB_DUMP for ESP, association, <all fields>

     <ad nauseam...>

 

 

6 安全考慮

 

      本文檔討論在一個操作系統中建立、讀取、修改和刪除安全關聯。只有可信的、

   特權用戶和進程能夠執行這些操作。現在還不清楚,在沒有可信的特權用戶概念的

   操作系統中,這個機制能否提供任何安全。

 

       如果無特權用戶能夠執行任何上述操作,那麼操作系統實際上不能提供安全服

   務。如果攻擊者知道使用的密鑰和算法,那麼加密不能提供任何保護。

 

       這個機制不是萬能藥,但是可以成爲建立安全網絡的重要的操作系統組件。

 

       用戶應該知道,本規範的具體實現提供的安全質量是完全依賴於操作系統的全

   面安全,PF_KEY實現的正確性,連接PF_KEY的程序的安全和正確性。當實現PF_KEY

   和相關的操作系統的安全關聯組件時,應使用更高質量保證的開發技術。

 

 

致謝

 

   The authors of this document are listed primarily in alphabetical

   order.  Randall Atkinson and Ron Lee provided useful feedback on

   earlier versions of this document.

 

   At one time or other, all of the authors worked at the Center for

   High Assurance Computer Systems at the U.S.  Naval Research

   Laboratory. This work was sponsored by the Information Security

   Program Office (PMW-161), U.S.  Space and Naval Warfare Systems

   Command (SPAWAR) and the Computing Systems Technology Office, Defense

   Advanced Research Projects Agency (DARPA/CSTO). We really appreciate

   their sponsorship of our efforts and their continued support of

   PF_KEY development. Without that support, PF_KEY would not exist.

 

   The "CONFORMANCE and COMPLIANCE" wording was taken from [MSST98].

 

   Finally, the authors would like to thank those who sent in comments

   and questions on the various iterations of this document. This

   specification and implementations of it are discussed on the PF_KEY

   mailing list. If you would like to be added to this list, send a note

   to <[email protected]>.

 

 

參考

 

   [AMPMC96] Randall J. Atkinson, Daniel L. McDonald, Bao G. Phan, Craig

   W. Metz, and Kenneth C. Chin, "Implementation of IPv6 in 4.4-Lite

   BSD", Proceedings of the 1996 USENIX Conference, San Diego, CA,

   January 1996, USENIX Association.

 

   [Atk95a] Atkinson, R., "IP Security Architecture", RFC 1825, August

   1995.

 

   [Atk95b] Atkinson, R., "IP Authentication Header", RFC 1826, August

   1995.

 

   [Atk95c] Atkinson, R., "IP Encapsulating Security Payload", RFC 1827,

   August 1995.

 

   [Atk97] Atkinson, R., "Key Exchange Delegation Record for the Domain

   Name System", RFC 2230, October 1997.

 

   [BA97] Baker, F., and R. Atkinson, "RIP-2 MD5 Authentication", RFC

   2082, January 1997.

 

   [Biba77] K. J. Biba, "Integrity Considerations for Secure Computer

   Systems", MTR-3153, The MITRE Corporation, June 1975; ESD-TR-76-372,

   April 1977.

 

   [BL74] D. Elliot Bell and Leonard J. LaPadula, "Secure Computer

   Systems: Unified Exposition and Multics Interpretation", MTR 2997,

   The MITRE Corporation, April 1974. (AD/A 020 445)

 

   [Bra97] Bradner, S., "Key words for use in RFCs to Indicate

   Requirement Levels", BCP 14, RFC 2119, March 1997.

 

   [CW87] D. D. Clark and D. R. Wilson, "A Comparison of Commercial and

   Military Computer Security Policies", Proceedings of the 1987

   Symposium on Security and Privacy, pp. 184-195, IEEE Computer

   Society, Washington, D.C., 1987.

 

   [DIA] US Defense Intelligence Agency (DIA), "Compartmented Mode

   Workstation Specification", Technical Report DDS-2600-6243-87.

 

   [GK98] Glenn, R., and S. Kent, "The NULL Encryption Algorithm and Its

   Use with IPsec", Work in Progress.

 

   [HM97a] Harney, H., and C. Muckenhirn, "Group Key Management Protocol

   (GKMP) Specification", RFC 2093, July 1997.

 

   [HM97b] Harney, H., and C. Muckenhirn, "Group Key Management Protocol

   (GKMP) Architecture", RFC 2094, July 1997.

 

   [MD98] Madsen, C., and N. Doraswamy, "The ESP DES-CBC Cipher

   Algorithm With Explicit IV", Work in Progress.

 

   [MG98a] Madsen, C., and R. Glenn, "The Use of HMAC-MD5-96 within ESP

   and AH", Work in Progress.

 

   [MG98b] Madsen, C., and R. Glenn, "The Use of HMAC-SHA-1-96 within

   ESP and AH", Work in Progress.

 

   [MSST98] Maughan, D., Schertler, M., Schneider, M., and J. Turner,

   "Internet Security Association and Key Management Protocol (ISAKMP)",

   Work in Progress.

 

   [Moy98] Moy, J., "OSPF Version 2", STD 54, RFC 2328, April 1998.

 

   [Per97] Perkins, C., "IP Mobility Support", RFC 2002, October 1996.

 

   [Pip98] Piper, D., "The Internet IP Security Domain of Interpretation

   for ISAKMP", Work in Progress.

 

   [Sch96] Bruce Schneier, Applied Cryptography, p. 360, John Wiley &

   Sons, Inc., 1996.

 

   [Skl91] Keith Sklower, "A Tree-based Packet Routing Table for

   Berkeley UNIX", Proceedings of the Winter 1991 USENIX Conference,

   Dallas, TX, USENIX Association. 1991.  pp. 93-103.

 

 

放棄聲明

 

   The views and specification here are those of the editors and are not

   necessarily those of their employers.  The employers have not passed

   judgment on the merits, if any, of this work.  The editors and their

   employers specifically disclaim responsibility for any problems

   arising from correct or incorrect implementation or use of this

   specification.

 

 

作者地址

 

   Daniel L. McDonald

   Sun Microsystems, Inc.

   901 San Antonio Road, MS UMPK17-202

   Palo Alto, CA 94303

 

   Phone: +1 650 786 6815

   EMail: [email protected]

 

 

   Craig Metz

   (for Code 5544)

   U.S. Naval Research Laboratory

   4555 Overlook Ave. SW

   Washington, DC 20375

 

   Phone: (DSN) 754-8590

   EMail: [email protected]

 

 

   Bao G. Phan

   U. S. Naval Research Laboratory

 

   EMail: [email protected]

 

 

附錄A:混雜模式發送/接收消息擴展

 

       內核支持PF_KEY,出於開發和調試目的,可以實現一些擴展。如果這樣做,必

   須按這裏的規定實現。具體實現可以要求程序具有額外的特權去執行混雜模式的發

   送、接收操作。

 

       SADB_X_PROMISC消息允許一個程序在“混雜模式”下發送和接收消息。該消息

   有兩種格式:控制和數據。控制格式只包含一個消息頭,用於觸發混雜接收功能。

   sadb_msg_satype的值爲1啓動混雜消息接收,值爲0禁止。

 

       第二種格式是數據格式,用於發送或接收未處理的消息。數據格式的消息由兩

   個消息頭組成:一個是SADB_X_PROMISC消息頭,一個是截獲的消息。

 

       發自應用程序的數據消息,發送至由sadb_msg_seq值(非零)指定進程的任一

   套接字,或者發送至所有PF_KEY套接字,如果sadb_msg_seq值爲零。這些消息沒有

   被PF_KEY接口做任何處理(包括健全檢查)。混雜發送功能允許應用程序像內核一

   樣發送消息,也允許發送錯誤消息。

 

       如果混雜接收功能啓動,能夠接收其它程序或內核通過PF_KEY發送的消息,在

   被PF_KEY接口處理之前(包括健全檢查)。混雜接收功能允許應用程序接收所有其

   它使用PF_KEY發送的消息。

 

     SADB_X_PROMISC消息機制如下:

 

         用戶進程發送控制格式的SADB_X_PROMISC消息至內核。

 

         <base>

 

         內核返回SADB_X_PROMISC消息至所有監聽進程。

 

         <base>

 

         用戶進程發送數據格式的SADB_X_PROMISC消息至內核。

 

         <base, base(, others)>

 

         內核發送封裝消息至目標進程。

 

         <base(, others)>

 

         如果混雜接收啓動,內核將封裝和發送所有通過PF_KEY接口發送的消息的副

         本。

 

         <base, base(, others)>

 

     錯誤:

 

         EPERM 沒有執行請求的操作的權利。

         ESRCH (數據格式的發送)sadb_msg_seq中指定的目標進程不存在或者沒有

               打開的PF_KEYv2套接字。

 

 

附錄B:被動轉換消息擴展

 

       SADB_X_PCHANGE消息是在被動方(aka,“監聽者”或“接收者”)與SADB_ACQUIRE

   相似的消息。當被動方會話偏離整個系統默認的安全服務時,這個消息有利於密鑰

   管理程序有效的操縱輸入的密鑰管理請求。如果被動會話請求只允許某些級別的安

   全服務,SADB_X_PCHANGE消息向已註冊的PF_KEY套接字表示服務已改變。與SADB_ACQUIRE

   不同,這個消息純粹是報告性質,守護進程與PF_KEY沒有其它的交互作用。

 

       SADB_X_PCHANGE消息可以被終端請求的安全服務改變或指定服務的取消觸發。

   對於前者,SADB_X_PCHANGE如同SADB_ACQUIRE消息,消息中包含sadb_proposal擴

   展指出首選的算法、生存期和其它屬性。當被動會話取消或者還原成默認行爲,將

   發出由_no_ sadb_proposal擴展構成的SADB_X_PCHANGE消息,指出系統異常取消。

 

       SADB_X_PCHANGE消息有兩種機制。第一種由內核發起:

 

        內核發送SADB_X_PCHANGE消息至註冊的套接字。

 

        <base, address(SD), (identity(SD),) (sensitivity,) (proposal)>

 

        注意: 地址(SD)擴展必須有會話所需的端口號。

 

        第二種用於用戶層使用者的SA。

 

        用戶進程發送SADB_X_PCHANGE消息至內核。

 

        <base, address(SD), (identity(SD),) (sensitivity,) (proposal)>

 

        內核返回SADB_X_PCHANGE消息至已註冊的套接字。

 

        <base, address(SD), (identity(SD),) (sensitivity,) (proposal)>

 

 

附錄C:密鑰管理專用數據擴展

 

       密鑰管理專用數據擴展依附於SADB_ADD或SADB_UPDATE消息,用於連接安全關

   聯上任意的一段數據。也可以用於密鑰管理程序,如果系統崩潰後需要重啓或恢復

   可以用於SADB_DUMP或SADB_GET消息獲得額外的情況。

 

           #define SADB_X_EXT_KMPRIVATE 17

 

           struct sadb_x_kmprivate {

                   uint16_t sadb_x_kmprivate_len;

                   uint16_t sadb_x_kmprivate_exttype;

                   uint32_t sadb_x_kmprivate_reserved;

           };

           /* sizeof(struct sadb_x_kmprivate) == 8 */

 

           /* 緊跟任意數據 */

 

 

       sadb_x_kmprivate擴展後可以是任意數據,存貯格式與安全關聯在內核中的格

   式相同,必須是64位邊界對齊。

 

 

附錄D:頭文件樣本

 

   /*

   This file defines structures and symbols for the PF_KEY Version 2

   key management interface. It was written at the U.S. Naval Research

   Laboratory. This file is in the public domain. The authors ask that

   you leave this credit intact on any copies of this file.

   */

   #ifndef __PFKEY_V2_H

   #define __PFKEY_V2_H 1

 

   #define PF_KEY_V2 2

   #define PFKEYV2_REVISION        199806L

 

   #define SADB_RESERVED    0

   #define SADB_GETSPI      1

   #define SADB_UPDATE      2

   #define SADB_ADD         3

   #define SADB_DELETE      4

   #define SADB_GET         5

   #define SADB_ACQUIRE     6

   #define SADB_REGISTER    7

   #define SADB_EXPIRE      8

   #define SADB_FLUSH       9

   #define SADB_DUMP        10

   #define SADB_X_PROMISC   11

   #define SADB_X_PCHANGE   12

   #define SADB_MAX         12

 

   struct sadb_msg {

     uint8_t sadb_msg_version;

     uint8_t sadb_msg_type;

     uint8_t sadb_msg_errno;

     uint8_t sadb_msg_satype;

     uint16_t sadb_msg_len;

     uint16_t sadb_msg_reserved;

     uint32_t sadb_msg_seq;

     uint32_t sadb_msg_pid;

   };

 

   struct sadb_ext {

     uint16_t sadb_ext_len;

     uint16_t sadb_ext_type;

   };

 

   struct sadb_sa {

     uint16_t sadb_sa_len;

     uint16_t sadb_sa_exttype;

     uint32_t sadb_sa_spi;

     uint8_t sadb_sa_replay;

     uint8_t sadb_sa_state;

     uint8_t sadb_sa_auth;

     uint8_t sadb_sa_encrypt;

     uint32_t sadb_sa_flags;

   };

 

   struct sadb_lifetime {

     uint16_t sadb_lifetime_len;

     uint16_t sadb_lifetime_exttype;

     uint32_t sadb_lifetime_allocations;

     uint64_t sadb_lifetime_bytes;

     uint64_t sadb_lifetime_addtime;

     uint64_t sadb_lifetime_usetime;

   };

 

   struct sadb_address {

     uint16_t sadb_address_len;

     uint16_t sadb_address_exttype;

     uint8_t sadb_address_proto;

     uint8_t sadb_address_prefixlen;

     uint16_t sadb_address_reserved;

   };

 

   struct sadb_key {

     uint16_t sadb_key_len;

     uint16_t sadb_key_exttype;

     uint16_t sadb_key_bits;

     uint16_t sadb_key_reserved;

   };

 

   struct sadb_ident {

     uint16_t sadb_ident_len;

     uint16_t sadb_ident_exttype;

     uint16_t sadb_ident_type;

     uint16_t sadb_ident_reserved;

     uint64_t sadb_ident_id;

   };

 

   struct sadb_sens {

     uint16_t sadb_sens_len;

     uint16_t sadb_sens_exttype;

     uint32_t sadb_sens_dpd;

     uint8_t sadb_sens_sens_level;

     uint8_t sadb_sens_sens_len;

     uint8_t sadb_sens_integ_level;

     uint8_t sadb_sens_integ_len;

     uint32_t sadb_sens_reserved;

   };

 

   struct sadb_prop {

     uint16_t sadb_prop_len;

     uint16_t sadb_prop_exttype;

     uint8_t sadb_prop_replay;

     uint8_t sadb_prop_reserved[3];

   };

 

   struct sadb_comb {

     uint8_t sadb_comb_auth;

     uint8_t sadb_comb_encrypt;

     uint16_t sadb_comb_flags;

     uint16_t sadb_comb_auth_minbits;

     uint16_t sadb_comb_auth_maxbits;

     uint16_t sadb_comb_encrypt_minbits;

     uint16_t sadb_comb_encrypt_maxbits;

     uint32_t sadb_comb_reserved;

     uint32_t sadb_comb_soft_allocations;

     uint32_t sadb_comb_hard_allocations;

     uint64_t sadb_comb_soft_bytes;

     uint64_t sadb_comb_hard_bytes;

     uint64_t sadb_comb_soft_addtime;

     uint64_t sadb_comb_hard_addtime;

     uint64_t sadb_comb_soft_usetime;

     uint64_t sadb_comb_hard_usetime;

   };

 

   struct sadb_supported {

     uint16_t sadb_supported_len;

     uint16_t sadb_supported_exttype;

     uint32_t sadb_supported_reserved;

   };

 

   struct sadb_alg {

     uint8_t sadb_alg_id;

     uint8_t sadb_alg_ivlen;

     uint16_t sadb_alg_minbits;

     uint16_t sadb_alg_maxbits;

     uint16_t sadb_alg_reserved;

   };

 

   struct sadb_spirange {

     uint16_t sadb_spirange_len;

     uint16_t sadb_spirange_exttype;

     uint32_t sadb_spirange_min;

     uint32_t sadb_spirange_max;

     uint32_t sadb_spirange_reserved;

   };

 

   struct sadb_x_kmprivate {

     uint16_t sadb_x_kmprivate_len;

     uint16_t sadb_x_kmprivate_exttype;

     uint32_t sadb_x_kmprivate_reserved;

   };

 

   #define SADB_EXT_RESERVED             0

   #define SADB_EXT_SA                   1

   #define SADB_EXT_LIFETIME_CURRENT     2

   #define SADB_EXT_LIFETIME_HARD        3

   #define SADB_EXT_LIFETIME_SOFT        4

   #define SADB_EXT_ADDRESS_SRC          5

   #define SADB_EXT_ADDRESS_DST          6

   #define SADB_EXT_ADDRESS_PROXY        7

   #define SADB_EXT_KEY_AUTH             8

   #define SADB_EXT_KEY_ENCRYPT          9

   #define SADB_EXT_IDENTITY_SRC         10

   #define SADB_EXT_IDENTITY_DST         11

   #define SADB_EXT_SENSITIVITY          12

   #define SADB_EXT_PROPOSAL             13

   #define SADB_EXT_SUPPORTED_AUTH       14

   #define SADB_EXT_SUPPORTED_ENCRYPT    15

   #define SADB_EXT_SPIRANGE             16

   #define SADB_X_EXT_KMPRIVATE          17

   #define SADB_EXT_MAX                  17

   #define SADB_SATYPE_UNSPEC    0

   #define SADB_SATYPE_AH        2

   #define SADB_SATYPE_ESP       3

   #define SADB_SATYPE_RSVP      5

   #define SADB_SATYPE_OSPFV2    6

   #define SADB_SATYPE_RIPV2     7

   #define SADB_SATYPE_MIP       8

   #define SADB_SATYPE_MAX       8

 

   #define SADB_SASTATE_LARVAL   0

   #define SADB_SASTATE_MATURE   1

   #define SADB_SASTATE_DYING    2

   #define SADB_SASTATE_DEAD     3

   #define SADB_SASTATE_MAX      3

 

   #define SADB_SAFLAGS_PFS      1

 

   #define SADB_AALG_NONE        0

   #define SADB_AALG_MD5HMAC     2

   #define SADB_AALG_SHA1HMAC    3

 

   #define SADB_AALG_MAX         3

 

   #define SADB_EALG_NONE        0

   #define SADB_EALG_DESCBC      2

   #define SADB_EALG_3DESCBC     3

   #define SADB_EALG_NULL        11

   #define SADB_EALG_MAX         11

 

   #define SADB_IDENTTYPE_RESERVED   0

   #define SADB_IDENTTYPE_PREFIX     1

   #define SADB_IDENTTYPE_FQDN       2

   #define SADB_IDENTTYPE_USERFQDN   3

   #define SADB_IDENTTYPE_MAX        3

 

   #define SADB_KEY_FLAGS_MAX 0

   #endif /* __PFKEY_V2_H */

 

 

附錄E:修改記錄

 

   The following changes were made between 05 and 06:

 

   * Last change before becoming an informational RFC.  Removed all

     Internet-Draft references.  Also standardized citation strings.

     Now cite RFC 2119 for MUST, etc.

 

   * New appendix on optional KM private data extension.

 

   * Fixed example to indicate the ACQUIRE messages with errno mean

     KM failure.

 

   * Added SADB_EALG_NULL.

 

   * Clarified proxy examples to match definition of PROXY address being

     the inner packet's source address.  (Basically a sign-flip.  The

     example still shows how to protect against policy vulnerabilities

     in tunnel endpoints.)

 

   * Loosened definition of a destination address to include broadcast.

 

   * Recommended that LARVAL security associations have implicit short

     lifetimes.

 

   The following changes were made between 04 and 05:

 

   * New appendix on Passive Change message.

 

   * New sadb_address_prefixlen field.

 

   * Small clarifications on sadb_ident_id usage.

 

   * New PFKEYV2_REVISION value.

 

   * Small clarification on what a PROXY address is.

 

   * Corrected sadb_spirange_{min,max} language.

 

   * In ADD messages that are in response to an ACQUIRE, the

     sadb_msg_seq MUST be the same as that of the originating ACQUIRE.

 

   * Corrected ACQUIRE message behavior, ACQUIRE message SHOULD send up

     PROXY addresses when it needs them.

 

   * Clarification on SADB_EXPIRE and user-level security protocols.

 

   The following changes were made between 03 and 04:

 

 

   * Stronger language about manual keying.

 

   * PFKEYV2_REVISION, ala POSIX.

 

   * Put in language about sockaddr ports in ACQUIRE messages.

 

   * Mention of asymmetric algorithms.

 

   * New sadb_ident_id field for easier construction of USER_FQDN

     identity strings.

 

   * Caveat about source addresses not always used for collision

     detection. (e.g. IPsec)

 

   The following changes were made between 02 and 03:

 

 

   * Formatting changes.

 

   * Many editorial cleanups, rewordings, clarifications.

 

   * Restrictions that prevent many strange and invalid cases.

 

   * Added definitions section.

 

   * Removed connection identity type (this will reappear when it is

     more clear what it should look like).

 

   * Removed 5.2.1 (Why involve the kernel?).

 

   * Removed INBOUND, OUTBOUND, and FORWARD flags; they can be computed

     from src, dst, and proxy and you had to anyway for sanity checking.

 

   * Removed REPLAY flag; sadb_sa_replay==0 means the same thing.

 

   * Renamed bit lengths to "bits" to avoid potential confusion.

 

   * Explicitly listed lengths for structures.

 

   * Reworked identities to always use a string format.

 

   * Removed requirements for support of shutdown() and SO_USELOOPBACK.

 

   * 64 bit alignment and 64 bit lengths instead of 32 bit.

 

   * time_t replaced with uint64 in lifetimes.

 

   * Inserted Appendix A (SADB_X_PROMISC) and Appendix B (SAMPLE HEADER

     FILE).

 

   * Explicit error if PF_KEY_V2 not set at socket() call.

 

   * More text on SO_USELOOPBACK.

 

   * Made fields names and symbol names more consistent.

 

   * Explicit error if PF_KEY_V2 is not in sadb_msg_version field.

 

   * Bytes lifetime field now a 64-bit quantity.

 

   * Explicit len/exttype wording.

 

   * Flattening out of extensions (LIFETIME_HARD, LIFETIME_SOFT, etc.)

 

   * UI example (0x123 == 0x1230 or 0x0123).

 

   * Cleaned up and fixed some message behavior examples.

 

   The following changes were made between 01 and 02:

 

   * Mentioned that people COULD use these same messages between user

     progs. (Also mentioned why you still might want to use the actual

     socket.)

 

   * Various wordsmithing changes.

 

   * Took out netkey/ directory, and make net/pfkeyv2.h

 

   * Inserted PF_KEY_V2 proto argument per C. Metz.

 

   * Mentioned other socket calls and how their PF_KEY behavior is

     undefined.

 

   * SADB_EXPIRE now communicates both hard and soft lifetime expires.

 

   * New "association" extension, even smaller base header.

 

   * Lifetime extension improvements.

 

   * Length now first in extensions.

 

   * Errors can be sent from kernel to user, also.

 

   * Examples section inserted.

 

   * Some bitfield cleanups, including STATE and SA_OPTIONS cleanup.

 

   * Key splitting now only across auth algorithm and encryption

     algorithm. Thanks for B. Sommerfeld for clues here.

 

   The following changes were made between 00 and 01:

 

   * Added this change log.

 

   * Simplified TLV header syntax.

 

   * Splitting of algorithms. This may be controversial, but it allows

     PF_KEY to be used for more than just IPsec. It also allows some

     kinds of policies to be placed in the KMd easier.

 

   * Added solid definitions and formats for certificate identities,

     multiple keys, etc.

 

   * Specified how keys are to be layed out (most-to-least bits).

 

   * Changed sequence number semantics to be like an RPC transaction ID

     number.

 

 

附錄F:版權聲明

 

   Copyright (C) The Internet Society (1998).  All Rights Reserved.

 

   This document and translations of it may be copied and furnished to

   others, and derivative works that comment on or otherwise explain it

   or assist in its implementation may be prepared, copied, published

   and distributed, in whole or in part, without restriction of any

   kind, provided that the above copyright notice and this paragraph are

   included on all such copies and derivative works.  However, this

   document itself may not be modified in any way, such as by removing

   the copyright notice or references to the Internet Society or other

   Internet organizations, except as needed for the purpose of

   developing Internet standards in which case the procedures for

   copyrights defined in the Internet Standards process must be

   followed, or as required to translate it into languages other than

   English.

 

   The limited permissions granted above are perpetual and will not be

   revoked by the Internet Society or its successors or assigns.

 

   This document and the information contained herein is provided on an

   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING

   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING

   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION

   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF

   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

RFC2367——PF_KEY Key Management API, Version 2            PF_KEY Key Management API, Version 2

 

 

1

RFC文檔中文翻譯計劃

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章