├── .gitignore ├── LICENSE ├── Makefile ├── Pipfile ├── README.md ├── __init__.py ├── docs ├── conf.py ├── ike.rst ├── ike.util.rst ├── index.rst ├── modules.rst └── readme.rst ├── draft-kivinen-ipsecme-ikev2-minimal-01.html ├── ike ├── __init__.py ├── const.py ├── initiator.py ├── payloads.py ├── proposal.py ├── protocol.py └── util │ ├── __init__.py │ ├── cipher.py │ ├── conv.py │ ├── dh.py │ ├── dump.py │ ├── external.py │ ├── prf.py │ └── pubkey.py ├── setup.py └── tests ├── ipsec.conf ├── ipsec.secrets ├── peer.pem ├── private_key.pem ├── public_key.pem └── strongswan.pem /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | 29 | # Translations 30 | *.mo 31 | 32 | # Mr Developer 33 | .mr.developer.cfg 34 | .project 35 | .pydevproject 36 | 37 | # PyCharm 38 | .idea 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2014 Kimmo Parviainen-Jalanko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: clean doc 2 | 3 | release: pypi 4 | 5 | clean-doc: 6 | rm docs/ike.rst docs/ike.util.rst docs/modules.rst || true 7 | 8 | doc: clean-doc 9 | pandoc -t rst README.md > README.rst 10 | cp README.rst docs/readme.rst 11 | sphinx-apidoc -o docs/ ike 12 | sphinx-build docs docs/_build 13 | git add docs/*.rst 14 | cd docs/_build && zip -r ../../docs.zip . 15 | 16 | clean: clean-doc 17 | rm -rf __pycache__ build dist README.rst *.zip || true 18 | 19 | pypi: 20 | python setup.py sdist bdist upload 21 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | 3 | url = "https://pypi.python.org/simple" 4 | verify_ssl = true 5 | name = "pypi" 6 | 7 | 8 | [requires] 9 | 10 | python_version = "3.6" 11 | 12 | 13 | [packages] 14 | 15 | cryptography = "*" 16 | docopt = "*" 17 | rsa = "*" 18 | 19 | 20 | [dev-packages] 21 | 22 | twine = "*" 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | About ike 2 | ===== 3 | 4 | The goal of this project is to be a minimalistic IKEv2 (RFC 5996) implementation in Python. 5 | 6 | ## Status 7 | This project is in early stages. Use at own risk. 8 | 9 | It will make your IP stack talk ESP to the remote peer. 10 | 11 | What it can do: 12 | 13 | - Act as an initiator 14 | - Authenticate itself and peer using raw RSA keys. 15 | - Install ESP SAs and SPD entries to use the key material via `setkey` command from ipsec-tools. 16 | 17 | Limitations (hardcoded values): 18 | 19 | - Cipher algorithm is Camellia in CBC mode with 256 bit keys. 20 | - HMAC / Hash / PRF algorithm is SHA2/256. 21 | - IKE group is Diffie-Hellman modp 14. 22 | - Authentication (both own private and peer public) key file paths are hardcoded. 23 | - 'setkey' syntax is of whatever the ipsec-tools on Debian 7.1 accept. 24 | - Traffic selectors are myip:any:0-65535 <-> peerip:any:0-65535 25 | 26 | ## Design principles 27 | 28 | - Minimal amount of code. 29 | - Support *MUST* features of draft-kivinen-ipsecme-ikev2-rfc5996bis-02 (RFC 5996 30 | successor) 31 | - Use strongest algorithms possible. 32 | 33 | ## Documentation 34 | You can read the Documentation at https://pythonhosted.org/ike 35 | 36 | ### What this project is *NOT* going to be 37 | 38 | - ISAKMP (IKEv1) RFC 2409 compliant 39 | - IPSec data plane / ESP protocol 40 | 41 | ## License 42 | 43 | * MIT License 44 | 45 | ## References 46 | 47 | * http://tools.ietf.org/html/draft-kivinen-ipsecme-ikev2-rfc5996bis-02 48 | * http://tools.ietf.org/html/draft-kivinen-ipsecme-ikev2-minimal-01 49 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013 Kimmo Parviainen-Jalanko. 4 | # 5 | import operator 6 | import const 7 | 8 | __author__ = 'kimvais' 9 | 10 | __version__ = '0.0.1' 11 | 12 | __license__ = "MIT" 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # ike documentation build configuration file, created by 5 | # sphinx-quickstart on Thu Apr 3 19:30:36 2014. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | import sys 17 | import os 18 | 19 | # If extensions (or modules to document with autodoc) are in another directory, 20 | # add these directories to sys.path here. If the directory is relative to the 21 | # documentation root, use os.path.abspath to make it absolute, like shown here. 22 | sys.path.insert(0, os.path.abspath('..')) 23 | 24 | from ike import __version__ 25 | # -- General configuration ------------------------------------------------ 26 | 27 | # If your documentation needs a minimal Sphinx version, state it here. 28 | #needs_sphinx = '1.0' 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | 'sphinx.ext.autodoc', 35 | 'sphinx.ext.todo', 36 | 'sphinx.ext.coverage', 37 | ] 38 | 39 | # Add any paths that contain templates here, relative to this directory. 40 | templates_path = ['_templates'] 41 | 42 | # The suffix of source filenames. 43 | source_suffix = '.rst' 44 | 45 | # The encoding of source files. 46 | #source_encoding = 'utf-8-sig' 47 | 48 | # The master toctree document. 49 | master_doc = 'index' 50 | 51 | # General information about the project. 52 | project = 'ike' 53 | copyright = '2014, Kimmo Parviainen-Jalanko' 54 | 55 | # The version info for the project you're documenting, acts as replacement for 56 | # |version| and |release|, also used in various other places throughout the 57 | # built documents. 58 | # 59 | # The short X.Y version. 60 | version = '{}.{}.{}'.format(*__version__) 61 | # The full version, including alpha/beta/rc tags. 62 | release = version 63 | 64 | # The language for content autogenerated by Sphinx. Refer to documentation 65 | # for a list of supported languages. 66 | #language = None 67 | 68 | # There are two options for replacing |today|: either, you set today to some 69 | # non-false value, then it is used: 70 | #today = '' 71 | # Else, today_fmt is used as the format for a strftime call. 72 | #today_fmt = '%B %d, %Y' 73 | 74 | # List of patterns, relative to source directory, that match files and 75 | # directories to ignore when looking for source files. 76 | exclude_patterns = ['_build'] 77 | 78 | # The reST default role (used for this markup: `text`) to use for all 79 | # documents. 80 | #default_role = None 81 | 82 | # If true, '()' will be appended to :func: etc. cross-reference text. 83 | #add_function_parentheses = True 84 | 85 | # If true, the current module name will be prepended to all description 86 | # unit titles (such as .. function::). 87 | #add_module_names = True 88 | 89 | # If true, sectionauthor and moduleauthor directives will be shown in the 90 | # output. They are ignored by default. 91 | #show_authors = False 92 | 93 | # The name of the Pygments (syntax highlighting) style to use. 94 | pygments_style = 'sphinx' 95 | 96 | # A list of ignored prefixes for module index sorting. 97 | #modindex_common_prefix = [] 98 | 99 | # If true, keep warnings as "system message" paragraphs in the built documents. 100 | #keep_warnings = False 101 | 102 | 103 | # -- Options for HTML output ---------------------------------------------- 104 | 105 | # The theme to use for HTML and HTML Help pages. See the documentation for 106 | # a list of builtin themes. 107 | html_theme = 'default' 108 | 109 | # Theme options are theme-specific and customize the look and feel of a theme 110 | # further. For a list of options available for each theme, see the 111 | # documentation. 112 | #html_theme_options = {} 113 | 114 | # Add any paths that contain custom themes here, relative to this directory. 115 | #html_theme_path = [] 116 | 117 | # The name for this set of Sphinx documents. If None, it defaults to 118 | # " v documentation". 119 | #html_title = None 120 | 121 | # A shorter title for the navigation bar. Default is the same as html_title. 122 | #html_short_title = None 123 | 124 | # The name of an image file (relative to this directory) to place at the top 125 | # of the sidebar. 126 | #html_logo = None 127 | 128 | # The name of an image file (within the static path) to use as favicon of the 129 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 130 | # pixels large. 131 | #html_favicon = None 132 | 133 | # Add any paths that contain custom static files (such as style sheets) here, 134 | # relative to this directory. They are copied after the builtin static files, 135 | # so a file named "default.css" will overwrite the builtin "default.css". 136 | html_static_path = ['_static'] 137 | 138 | # Add any extra paths that contain custom files (such as robots.txt or 139 | # .htaccess) here, relative to this directory. These files are copied 140 | # directly to the root of the documentation. 141 | #html_extra_path = [] 142 | 143 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 144 | # using the given strftime format. 145 | #html_last_updated_fmt = '%b %d, %Y' 146 | 147 | # If true, SmartyPants will be used to convert quotes and dashes to 148 | # typographically correct entities. 149 | #html_use_smartypants = True 150 | 151 | # Custom sidebar templates, maps document names to template names. 152 | #html_sidebars = {} 153 | 154 | # Additional templates that should be rendered to pages, maps page names to 155 | # template names. 156 | #html_additional_pages = {} 157 | 158 | # If false, no module index is generated. 159 | #html_domain_indices = True 160 | 161 | # If false, no index is generated. 162 | #html_use_index = True 163 | 164 | # If true, the index is split into individual pages for each letter. 165 | #html_split_index = False 166 | 167 | # If true, links to the reST sources are added to the pages. 168 | #html_show_sourcelink = True 169 | 170 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 171 | #html_show_sphinx = True 172 | 173 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 174 | #html_show_copyright = True 175 | 176 | # If true, an OpenSearch description file will be output, and all pages will 177 | # contain a tag referring to it. The value of this option must be the 178 | # base URL from which the finished HTML is served. 179 | #html_use_opensearch = '' 180 | 181 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 182 | #html_file_suffix = None 183 | 184 | # Output file base name for HTML help builder. 185 | htmlhelp_basename = 'ikedoc' 186 | 187 | 188 | # -- Options for LaTeX output --------------------------------------------- 189 | 190 | latex_elements = { 191 | # The paper size ('letterpaper' or 'a4paper'). 192 | #'papersize': 'letterpaper', 193 | 194 | # The font size ('10pt', '11pt' or '12pt'). 195 | #'pointsize': '10pt', 196 | 197 | # Additional stuff for the LaTeX preamble. 198 | #'preamble': '', 199 | } 200 | 201 | # Grouping the document tree into LaTeX files. List of tuples 202 | # (source start file, target name, title, 203 | # author, documentclass [howto, manual, or own class]). 204 | latex_documents = [ 205 | ('index', 'ike.tex', 'ike Documentation', 206 | 'Kimmo Parviainen-Jalanko', 'manual'), 207 | ] 208 | 209 | # The name of an image file (relative to this directory) to place at the top of 210 | # the title page. 211 | #latex_logo = None 212 | 213 | # For "manual" documents, if this is true, then toplevel headings are parts, 214 | # not chapters. 215 | #latex_use_parts = False 216 | 217 | # If true, show page references after internal links. 218 | #latex_show_pagerefs = False 219 | 220 | # If true, show URL addresses after external links. 221 | #latex_show_urls = False 222 | 223 | # Documents to append as an appendix to all manuals. 224 | #latex_appendices = [] 225 | 226 | # If false, no module index is generated. 227 | #latex_domain_indices = True 228 | 229 | 230 | # -- Options for manual page output --------------------------------------- 231 | 232 | # One entry per manual page. List of tuples 233 | # (source start file, name, description, authors, manual section). 234 | man_pages = [ 235 | ('index', 'ike', 'ike Documentation', 236 | ['Kimmo Parviainen-Jalanko'], 1) 237 | ] 238 | 239 | # If true, show URL addresses after external links. 240 | #man_show_urls = False 241 | 242 | 243 | # -- Options for Texinfo output ------------------------------------------- 244 | 245 | # Grouping the document tree into Texinfo files. List of tuples 246 | # (source start file, target name, title, author, 247 | # dir menu entry, description, category) 248 | texinfo_documents = [ 249 | ('index', 'ike', 'ike Documentation', 250 | 'Kimmo Parviainen-Jalanko', 'ike', 'One line description of project.', 251 | 'Miscellaneous'), 252 | ] 253 | 254 | # Documents to append as an appendix to all manuals. 255 | #texinfo_appendices = [] 256 | 257 | # If false, no module index is generated. 258 | #texinfo_domain_indices = True 259 | 260 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 261 | #texinfo_show_urls = 'footnote' 262 | 263 | # If true, do not generate a @detailmenu in the "Top" node's menu. 264 | #texinfo_no_detailmenu = False 265 | -------------------------------------------------------------------------------- /docs/ike.rst: -------------------------------------------------------------------------------- 1 | ike package 2 | =========== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | ike.util 10 | 11 | Submodules 12 | ---------- 13 | 14 | ike.const module 15 | ---------------- 16 | 17 | .. automodule:: ike.const 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | 22 | ike.initiator module 23 | -------------------- 24 | 25 | .. automodule:: ike.initiator 26 | :members: 27 | :undoc-members: 28 | :show-inheritance: 29 | 30 | ike.payloads module 31 | ------------------- 32 | 33 | .. automodule:: ike.payloads 34 | :members: 35 | :undoc-members: 36 | :show-inheritance: 37 | 38 | ike.proposal module 39 | ------------------- 40 | 41 | .. automodule:: ike.proposal 42 | :members: 43 | :undoc-members: 44 | :show-inheritance: 45 | 46 | ike.protocol module 47 | ------------------- 48 | 49 | .. automodule:: ike.protocol 50 | :members: 51 | :undoc-members: 52 | :show-inheritance: 53 | 54 | 55 | Module contents 56 | --------------- 57 | 58 | .. automodule:: ike 59 | :members: 60 | :undoc-members: 61 | :show-inheritance: 62 | -------------------------------------------------------------------------------- /docs/ike.util.rst: -------------------------------------------------------------------------------- 1 | ike.util package 2 | ================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | ike.util.cipher module 8 | ---------------------- 9 | 10 | .. automodule:: ike.util.cipher 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | ike.util.conv module 16 | -------------------- 17 | 18 | .. automodule:: ike.util.conv 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | ike.util.dh module 24 | ------------------ 25 | 26 | .. automodule:: ike.util.dh 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | ike.util.dump module 32 | -------------------- 33 | 34 | .. automodule:: ike.util.dump 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | ike.util.external module 40 | ------------------------ 41 | 42 | .. automodule:: ike.util.external 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | ike.util.prf module 48 | ------------------- 49 | 50 | .. automodule:: ike.util.prf 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | 55 | ike.util.pubkey module 56 | ---------------------- 57 | 58 | .. automodule:: ike.util.pubkey 59 | :members: 60 | :undoc-members: 61 | :show-inheritance: 62 | 63 | 64 | Module contents 65 | --------------- 66 | 67 | .. automodule:: ike.util 68 | :members: 69 | :undoc-members: 70 | :show-inheritance: 71 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. ike documentation master file, created by 2 | sphinx-quickstart on Thu Apr 3 19:30:36 2014. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to ike's documentation! 7 | =============================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | readme 15 | ike 16 | modules 17 | 18 | .. automodule:: ike 19 | :members: 20 | 21 | 22 | 23 | Indices and tables 24 | ================== 25 | 26 | * :ref:`genindex` 27 | * :ref:`modindex` 28 | * :ref:`search` 29 | 30 | -------------------------------------------------------------------------------- /docs/modules.rst: -------------------------------------------------------------------------------- 1 | ike 2 | === 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | ike 8 | -------------------------------------------------------------------------------- /docs/readme.rst: -------------------------------------------------------------------------------- 1 | About ike 2 | ========= 3 | 4 | The goal of this project is to be a minimalistic IKEv2 (RFC 5996) 5 | implementation in Python. 6 | 7 | Status 8 | ------ 9 | 10 | This project is in early stages. Use at own risk. 11 | 12 | It will make your IP stack talk ESP to the remote peer. 13 | 14 | What it can do: 15 | 16 | - Act as an initiator 17 | - Authenticate itself and peer using raw RSA keys. 18 | - Install ESP SAs and SPD entries to use the key material via 19 | ``setkey`` command from ipsec-tools. 20 | 21 | Limitations (hardcoded values): 22 | 23 | - Cipher algorithm is Camellia in CBC mode with 256 bit keys. 24 | - HMAC / Hash / PRF algorithm is SHA2/256. 25 | - IKE group is Diffie-Hellman modp 14. 26 | - Authentication (both own private and peer public) key file paths are 27 | hardcoded. 28 | - 'setkey' syntax is of whatever the ipsec-tools on Debian 7.1 accept. 29 | - Traffic selectors are myip:any:0-65535 <-> peerip:any:0-65535 30 | 31 | Design principles 32 | ----------------- 33 | 34 | - Minimal amount of code. 35 | - Support *MUST* features of draft-kivinen-ipsecme-ikev2-rfc5996bis-02 36 | (RFC 5996 successor) 37 | - Use strongest algorithms possible. 38 | 39 | Documentation 40 | ------------- 41 | 42 | You can read the Documentation at https://pythonhosted.org/ike 43 | 44 | What this project is *NOT* going to be 45 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 46 | 47 | - ISAKMP (IKEv1) RFC 2409 compliant 48 | - IPSec data plane / ESP protocol 49 | 50 | License 51 | ------- 52 | 53 | - MIT License 54 | 55 | References 56 | ---------- 57 | 58 | - http://tools.ietf.org/html/draft-kivinen-ipsecme-ikev2-rfc5996bis-02 59 | - http://tools.ietf.org/html/draft-kivinen-ipsecme-ikev2-minimal-01 60 | 61 | -------------------------------------------------------------------------------- /draft-kivinen-ipsecme-ikev2-minimal-01.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | draft-kivinen-ipsecme-ikev2-minimal-01 - Minimal IKEv2 18 | 19 | 20 | 99 | 107 | 108 | 134 | 135 | 136 |
137 |
143 | 149 |
150 | [Docs] [txt|pdf|xml] [Tracker] [Email] [Diff1] [Diff2] [Nits]
151 |
152 | Versions: 00 01
153 |
154 |
 155 | IP Security Maintenance and Extensions                        T. Kivinen
 156 | (ipsecme)                                                      AuthenTec
 157 | Internet-Draft                                           October 1, 2012
 158 | Intended status: Informational
 159 | Expires: April 4, 2013
 160 | 
 161 | 
 162 |                              Minimal IKEv2
 163 |                draft-kivinen-ipsecme-ikev2-minimal-01.txt
 164 | 
 165 | Abstract
 166 | 
 167 |    This document describes minimal version of the Internet Key Exchange
 168 |    version 2 (IKEv2) protocol.  IKEv2 is a component of IPsec used for
 169 |    performing mutual authentication and establishing and maintaining
 170 |    Security Associations (SAs).  IKEv2 includes several optional
 171 |    features, which are not needed in minimal implementations.  This
 172 |    document describes what is required from the minimal implementation,
 173 |    and also describes various optimizations which can be done.  The
 174 |    protocol described here is compliant with full IKEv2 with exception
 175 |    that this document only describes shared secret authentication (IKEv2
 176 |    requires support for certificate authentication in addition to shared
 177 |    secret authentication).
 178 | 
 179 |    This document does not update or modify RFC 5996, but provides more
 180 |    compact description of the minimal version of the protocol.  If this
 181 |    document and RFC 5996 conflicts then RFC 5996 is the authoritative
 182 |    description.
 183 | 
 184 | Status of this Memo
 185 | 
 186 |    This Internet-Draft is submitted in full conformance with the
 187 |    provisions of BCP 78 and BCP 79.
 188 | 
 189 |    Internet-Drafts are working documents of the Internet Engineering
 190 |    Task Force (IETF).  Note that other groups may also distribute
 191 |    working documents as Internet-Drafts.  The list of current Internet-
 192 |    Drafts is at http://datatracker.ietf.org/drafts/current/.
 193 | 
 194 |    Internet-Drafts are draft documents valid for a maximum of six months
 195 |    and may be updated, replaced, or obsoleted by other documents at any
 196 |    time.  It is inappropriate to use Internet-Drafts as reference
 197 |    material or to cite them other than as "work in progress."
 198 | 
 199 |    This Internet-Draft will expire on April 4, 2013.
 200 | 
 201 | Copyright Notice
 202 | 
 203 | 
 204 | 
 205 | 
 206 | Kivinen                   Expires April 4, 2013                 [Page 1]
 207 | 

 208 | Internet-Draft                Minimal IKEv2                 October 2012
 209 | 
 210 | 
 211 |    Copyright (c) 2012 IETF Trust and the persons identified as the
 212 |    document authors.  All rights reserved.
 213 | 
 214 |    This document is subject to BCP 78 and the IETF Trust's Legal
 215 |    Provisions Relating to IETF Documents
 216 |    (http://trustee.ietf.org/license-info) in effect on the date of
 217 |    publication of this document.  Please review these documents
 218 |    carefully, as they describe your rights and restrictions with respect
 219 |    to this document.  Code Components extracted from this document must
 220 |    include Simplified BSD License text as described in Section 4.e of
 221 |    the Trust Legal Provisions and are provided without warranty as
 222 |    described in the Simplified BSD License.
 223 | 
 224 |    This document may contain material from IETF Documents or IETF
 225 |    Contributions published or made publicly available before November
 226 |    10, 2008.  The person(s) controlling the copyright in some of this
 227 |    material may not have granted the IETF Trust the right to allow
 228 |    modifications of such material outside the IETF Standards Process.
 229 |    Without obtaining an adequate license from the person(s) controlling
 230 |    the copyright in such materials, this document may not be modified
 231 |    outside the IETF Standards Process, and derivative works of it may
 232 |    not be created outside the IETF Standards Process, except to format
 233 |    it for publication as an RFC or to translate it into languages other
 234 |    than English.
 235 | 
 236 | 
 237 | 
 238 | 
 239 | 
 240 | 
 241 | 
 242 | 
 243 | 
 244 | 
 245 | 
 246 | 
 247 | 
 248 | 
 249 | 
 250 | 
 251 | 
 252 | 
 253 | 
 254 | 
 255 | 
 256 | 
 257 | 
 258 | 
 259 | 
 260 | 
 261 | 
 262 | Kivinen                   Expires April 4, 2013                 [Page 2]
 263 | 

 264 | Internet-Draft                Minimal IKEv2                 October 2012
 265 | 
 266 | 
 267 | Table of Contents
 268 | 
 269 |    1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  4
 270 |      1.1.  Use Cases  . . . . . . . . . . . . . . . . . . . . . . . .  4
 271 |    2.  Exchanges  . . . . . . . . . . . . . . . . . . . . . . . . . .  6
 272 |      2.1.  Initial Exchange . . . . . . . . . . . . . . . . . . . . .  6
 273 |      2.2.  Other Exchanges  . . . . . . . . . . . . . . . . . . . . . 11
 274 |      2.3.  Generating Keying Material . . . . . . . . . . . . . . . . 12
 275 |    3.  Conformance Requirements . . . . . . . . . . . . . . . . . . . 14
 276 |    4.  Security Considerations  . . . . . . . . . . . . . . . . . . . 15
 277 |    5.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 16
 278 |    6.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 17
 279 |    7.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 18
 280 |      7.1.  Normative References . . . . . . . . . . . . . . . . . . . 18
 281 |      7.2.  Informative References . . . . . . . . . . . . . . . . . . 18
 282 |    Appendix A.  Header and Payload Formats  . . . . . . . . . . . . . 19
 283 |      A.1.  The IKE Header . . . . . . . . . . . . . . . . . . . . . . 19
 284 |      A.2.  Generic Payload Header . . . . . . . . . . . . . . . . . . 21
 285 |      A.3.  Security Association Payload . . . . . . . . . . . . . . . 22
 286 |        A.3.1.  Proposal Substructure  . . . . . . . . . . . . . . . . 24
 287 |        A.3.2.  Transform Substructure . . . . . . . . . . . . . . . . 25
 288 |        A.3.3.  Valid Transform Types by Protocol  . . . . . . . . . . 27
 289 |        A.3.4.  Transform Attributes . . . . . . . . . . . . . . . . . 28
 290 |      A.4.  Key Exchange Payload . . . . . . . . . . . . . . . . . . . 28
 291 |      A.5.  Identification Payloads  . . . . . . . . . . . . . . . . . 29
 292 |      A.6.  Certificate Payload  . . . . . . . . . . . . . . . . . . . 30
 293 |      A.7.  Certificate Request Payload  . . . . . . . . . . . . . . . 31
 294 |      A.8.  Authentication Payload . . . . . . . . . . . . . . . . . . 32
 295 |      A.9.  Nonce Payload  . . . . . . . . . . . . . . . . . . . . . . 33
 296 |      A.10. Notify Payload . . . . . . . . . . . . . . . . . . . . . . 33
 297 |        A.10.1. Notify Message Types . . . . . . . . . . . . . . . . . 34
 298 |      A.11. Traffic Selector Payload . . . . . . . . . . . . . . . . . 35
 299 |        A.11.1. Traffic Selector . . . . . . . . . . . . . . . . . . . 37
 300 |      A.12. Encrypted Payload  . . . . . . . . . . . . . . . . . . . . 38
 301 |    Appendix B.  Useful Optional Features  . . . . . . . . . . . . . . 41
 302 |      B.1.  IKE SA Delete Notification . . . . . . . . . . . . . . . . 41
 303 |      B.2.  Raw RSA keys . . . . . . . . . . . . . . . . . . . . . . . 42
 304 |    Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 44
 305 | 
 306 | 
 307 | 
 308 | 
 309 | 
 310 | 
 311 | 
 312 | 
 313 | 
 314 | 
 315 | 
 316 | 
 317 | 
 318 | Kivinen                   Expires April 4, 2013                 [Page 3]
 319 | 

 320 | Internet-Draft                Minimal IKEv2                 October 2012
 321 | 
 322 | 
 323 | 1.  Introduction
 324 | 
 325 |    This document tells what minimal IKEv2 implementation could look
 326 |    like.  Minimal IKEv2 implementation only supports initiator end of
 327 |    the protocol.  It only supports the initial IKE_SA_INIT and IKE_AUTH
 328 |    exchanges and does not initiate any other exchanges.  It also replies
 329 |    with empty (or error) message to all incoming requests.
 330 | 
 331 |    This means that most of the optional features of IKEv2 are left out:
 332 |    NAT Traversal, IKE SA rekey, Child SA Rekey, Multiple Child SAs,
 333 |    Deleting Child / IKE SAs, Configuration payloads, EAP authentication,
 334 |    COOKIEs etc.
 335 | 
 336 |    Some optimizations can be done because of limited set of supported
 337 |    features, and this text should not be considered for generic IKEv2
 338 |    implementations (for example Message IDs can be done as specified as
 339 |    implementation is only sending out IKE_SA_INIT and IKE_AUTH request,
 340 |    and do not ever send any other request).
 341 | 
 342 |    This document should be stand-alone, meaning everything needed to
 343 |    implement IKEv2 is copied here except the description of the
 344 |    cryptographic algorithms.  The IKEv2 specification has lots of
 345 |    background information and rationale which has been omitted from this
 346 |    document.
 347 | 
 348 |    Numerous additional numeric values from IANA registries have been
 349 |    omitted from this document, only those which are of interest for
 350 |    minimal implementation are listed in this document.
 351 | 
 352 |    For more information check the full IKEv2 specification in RFC 5996
 353 |    [RFC5996] and [IKEV2IANA].
 354 | 
 355 |    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
 356 |    "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
 357 |    document are to be interpreted as described in [RFC2119].
 358 | 
 359 | 1.1.  Use Cases
 360 | 
 361 |    One use case for this kind of minimal implementation is in small
 362 |    devices doing machine to machine communication.  In such environments
 363 |    the node initiating connections is usually very small and the other
 364 |    end of the communication channel is some kind of larger device.
 365 | 
 366 |    An example of the small initiating node could be an remote garage
 367 |    door opener device.  I.e. device having buttons which open and close
 368 |    garage door, and which connects to the home area network server over
 369 |    wireless link.
 370 | 
 371 | 
 372 | 
 373 | 
 374 | Kivinen                   Expires April 4, 2013                 [Page 4]
 375 | 

 376 | Internet-Draft                Minimal IKEv2                 October 2012
 377 | 
 378 | 
 379 |    Another example of the such device is some kind of sensor device, for
 380 |    example room temperature sensor, which sends periodic temperature
 381 |    data to some centralized node.
 382 | 
 383 |    Those devices are usually sleeping long times, and only wakes up
 384 |    because of user interaction or periodically.  The data transfer is
 385 |    always initiated from the sleeping node and after they send packets
 386 |    there might be ACKs or other packets coming back before they go back
 387 |    to sleep.  If some data needs to be transferred from server node to
 388 |    the small device, it can be implemented by polling, i.e. small node
 389 |    periodically polls for the server to see if it for example have some
 390 |    configuration changes or similar.
 391 | 
 392 | 
 393 | 
 394 | 
 395 | 
 396 | 
 397 | 
 398 | 
 399 | 
 400 | 
 401 | 
 402 | 
 403 | 
 404 | 
 405 | 
 406 | 
 407 | 
 408 | 
 409 | 
 410 | 
 411 | 
 412 | 
 413 | 
 414 | 
 415 | 
 416 | 
 417 | 
 418 | 
 419 | 
 420 | 
 421 | 
 422 | 
 423 | 
 424 | 
 425 | 
 426 | 
 427 | 
 428 | 
 429 | 
 430 | Kivinen                   Expires April 4, 2013                 [Page 5]
 431 | 

 432 | Internet-Draft                Minimal IKEv2                 October 2012
 433 | 
 434 | 
 435 | 2.  Exchanges
 436 | 
 437 | 2.1.  Initial Exchange
 438 | 
 439 |    All IKEv2 communications consist of pairs of messages: a request and
 440 |    a response.  The pair is called an "exchange", and is sometimes
 441 |    called a "request/response pair".  Every request requires a response.
 442 | 
 443 |    For every pair of IKEv2 messages, the initiator is responsible for
 444 |    retransmission in the event of a timeout.  The responder MUST never
 445 |    retransmit a response unless it receives a retransmission of the
 446 |    request.
 447 | 
 448 |    IKEv2 is a reliable protocol: the initiator MUST retransmit a request
 449 |    until it either receives a corresponding response or deems the IKE SA
 450 |    to have failed.  A retransmission from the initiator MUST be bitwise
 451 |    identical to the original request.  Retransmission times MUST
 452 |    increase exponentially.
 453 | 
 454 |    IKEv2 is run over UDP port 500.  All IKEv2 implementations MUST be
 455 |    able to send, receive, and process IKEv2 messages that are up to 1280
 456 |    octets long.  An implementation MUST accept incoming requests even if
 457 |    the source port is not 500, and MUST respond to the address and port
 458 |    from which the request was received.
 459 | 
 460 |    The minimal implementation of IKEv2 only uses first two exchanges
 461 |    called IKE_SA_INIT and IKE_AUTH.  Those are used to create the IKE SA
 462 |    and the first child SA.  In addition to those messages minimal IKEv2
 463 |    implementation need to understand CREATE_CHILD_SA request so it can
 464 |    reply with CREATE_CHILD_SA error response saying NO_ADDITIONAL_SAS to
 465 |    it, and understand INFORMATIONAL request so much, it can reply with
 466 |    empty INFORMATIONAL response to it.  There is no requirement to be
 467 |    able to respond to any other requests.
 468 | 
 469 |    All messages following the IKE_SA_INIT exchange are cryptographically
 470 |    protected using the cryptographic algorithms and keys negotiated in
 471 |    the IKE_SA_INIT exchange.
 472 | 
 473 |    Every IKEv2 message contains a Message ID as part of its fixed
 474 |    header.  This Message ID is used to match up requests and responses,
 475 |    and to identify retransmissions of messages.
 476 | 
 477 |    Minimal implementation need only support of being initiator, so it
 478 |    does not ever need to send any other request as one IKE_SA_INIT, and
 479 |    one IKE_AUTH message.  As those messages have fixed Message IDs (0
 480 |    and 1) it does not need to keep track of its own Message IDs for
 481 |    outgoing requests after that.
 482 | 
 483 | 
 484 | 
 485 | 
 486 | Kivinen                   Expires April 4, 2013                 [Page 6]
 487 | 

 488 | Internet-Draft                Minimal IKEv2                 October 2012
 489 | 
 490 | 
 491 |    Minimal implementations can also optimize Message ID handling of the
 492 |    incoming requests, as they do not need to protect incoming requests
 493 |    against replays.  This is possible because minimal implementation
 494 |    will only return error or empty notifications replies to incoming
 495 |    requests.  This means that any of those incoming requests do not have
 496 |    any effect on the minimal implementation, thus processing them again
 497 |    does not cause any harm.  Because of this the minimal implementation
 498 |    can always answer to request coming in, with the same Message ID than
 499 |    what the request had and then forget the request/response pair
 500 |    immediately.  This means there is no need to keep any kind of track
 501 |    of Message IDs of the incoming requests.
 502 | 
 503 |    In the following descriptions, the payloads contained in the message
 504 |    are indicated by names as listed below.
 505 | 
 506 |    Notation    Payload
 507 |    -----------------------------------------
 508 |    AUTH        Authentication
 509 |    CERTREQ     Certificate Request
 510 |    D           Delete
 511 |    HDR         IKE header (not a payload)
 512 |    IDi         Identification - Initiator
 513 |    IDr         Identification - Responder
 514 |    KE          Key Exchange
 515 |    Ni, Nr      Nonce
 516 |    N           Notify
 517 |    SA          Security Association
 518 |    SK          Encrypted and Authenticated
 519 |    TSi         Traffic Selector - Initiator
 520 |    TSr         Traffic Selector - Responder
 521 | 
 522 |    The initial exchanges are as follows:
 523 | 
 524 |    Initiator                         Responder
 525 |    -------------------------------------------------------------------
 526 |    HDR(SPIi=xxx, SPIr=0, IKE_SA_INIT,
 527 |        Flags: Initiator, Message ID=0),
 528 |        SAi1, KEi, Ni  -->
 529 | 
 530 |                       <--  HDR(SPIi=xxx, SPIr=yyy, IKE_SA_INIT,
 531 |                                Flags: Response, Message ID=0),
 532 |                                SAr1, KEr, Nr, [CERTREQ]
 533 | 
 534 |    HDR contains the Security Parameter Indexes (SPIs), version numbers,
 535 |    and flags of various sorts.  Each endpoint chooses one of the two
 536 |    SPIs and MUST choose them so as to be unique identifiers of an IKE
 537 |    SA.  An SPI value of zero is special: it indicates that the remote
 538 |    SPI value is not yet known by the sender.
 539 | 
 540 | 
 541 | 
 542 | Kivinen                   Expires April 4, 2013                 [Page 7]
 543 | 

 544 | Internet-Draft                Minimal IKEv2                 October 2012
 545 | 
 546 | 
 547 |    Incoming IKEv2 packets are mapped to an IKE SA only using the
 548 |    packet's SPI, not using (for example) the source IP address of the
 549 |    packet.
 550 | 
 551 |    The SAi1 payload states the cryptographic algorithms the initiator
 552 |    supports for the IKE SA.  The KEi and KEr payload contain Diffie-
 553 |    Hellman values and Ni and Nr are the nonces.  The SAr1 contains
 554 |    chosen cryptographic suite from initiator's offered choices.  Minimal
 555 |    implementation using shared secrets will ignore the CERTREQ payload.
 556 | 
 557 |    Minimal implementation will most likely support exactly one set of
 558 |    cryptographic algorithms, meaning the SAi1 payload will be static.
 559 |    It needs to check that the SAr1 received matches the proposal it
 560 |    sent.
 561 | 
 562 |    At this point in the negotiation, each party can generate SKEYSEED,
 563 |    from which all keys are derived for that IKE SA.
 564 | 
 565 |    SKEYSEED = prf(Ni | Nr, g^ir)
 566 | 
 567 |    {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr }
 568 |                    = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr )
 569 | 
 570 |    prf+ (K,S) = T1 | T2 | T3 | T4 | ...
 571 | 
 572 |    where:
 573 |    T1 = prf (K, S | 0x01)
 574 |    T2 = prf (K, T1 | S | 0x02)
 575 |    T3 = prf (K, T2 | S | 0x03)
 576 |    T4 = prf (K, T3 | S | 0x04)
 577 |    ...
 578 | 
 579 |    (indicating that the quantities SK_d, SK_ai, SK_ar, SK_ei, SK_er,
 580 |    SK_pi, and SK_pr are taken in order from the generated bits of the
 581 |    prf+). g^ir is the shared secret from the ephemeral Diffie-Hellman
 582 |    exchange. g^ir is represented as a string of octets in big endian
 583 |    order padded with zeros if necessary to make it the length of the
 584 |    modulus.  Ni and Nr are the nonces, stripped of any headers.
 585 | 
 586 |    The SK_d is used for deriving new keys for the Child SAs.  The SK_ai
 587 |    and SK_ar are used as a key to the integrity protection algorithm for
 588 |    authenticating the component messages of subsequent exchanges.  The
 589 |    SK_ei and SK_er are used for encrypting (and of course decrypting)
 590 |    all subsequent exchanges.  The SK_pi and SK_pr are used when
 591 |    generating an AUTH payload.  The lengths of SK_d, SK_pi, and SK_pr
 592 |    MUST be the preferred key length of the PRF agreed upon.
 593 | 
 594 |    A separate SK_e and SK_a is computed for each direction.  The keys
 595 | 
 596 | 
 597 | 
 598 | Kivinen                   Expires April 4, 2013                 [Page 8]
 599 | 

 600 | Internet-Draft                Minimal IKEv2                 October 2012
 601 | 
 602 | 
 603 |    used to protect messages from the original initiator are SK_ai and
 604 |    SK_ei.  The keys used to protect messages in the other direction are
 605 |    SK_ar and SK_er.  The notation SK { ... } indicates that these
 606 |    payloads are encrypted and integrity protected using that direction's
 607 |    SK_e and SK_a.
 608 | 
 609 |    Initiator                         Responder
 610 |    -------------------------------------------------------------------
 611 |    HDR(SPIi=xxx, SPIr=yyy, IKE_AUTH,
 612 |        Flags: Initiator, Message ID=1),
 613 |        SK {IDi, AUTH, SAi2, TSi, TSr,
 614 |            N(INITIAL_CONTACT)}  -->
 615 | 
 616 |                      <--  HDR(SPIi=xxx, SPIr=yyy, IKE_AUTH, Flags:
 617 |                                  Response, Message ID=1),
 618 |                                  SK {IDr, AUTH, SAr2, TSi, TSr}
 619 | 
 620 |    The initiator asserts its identity with the IDi payload, proves
 621 |    knowledge of the secret corresponding to IDi and integrity protects
 622 |    the contents of the first message using the AUTH payload.  The
 623 |    responder asserts its identity with the IDr payload, authenticates
 624 |    its identity and protects the integrity of the second message with
 625 |    the AUTH payload.
 626 | 
 627 |    As minimal implementation usually has only one host where it
 628 |    connects, and that means it has only one shared secret.  This means
 629 |    it does not need to care about IDr payload that much.  If the other
 630 |    end sends AUTH payload which initiator can verify using the shared
 631 |    secret it has, then it knows the other end is the peer it was
 632 |    configured to talk to.
 633 | 
 634 |    In the IKE_AUTH initiator sends SA offer(s) in the SAi2 payload, and
 635 |    the proposed Traffic Selectors for the proposed Child SA in the TSi
 636 |    and TSr payloads.  The responder replies with the accepted offer in
 637 |    an SAr2 payload, and selected Traffic Selectors.  The selected
 638 |    Traffic Selectors may be a subset of what the initiator proposed.
 639 | 
 640 |    In the minimal implementation both SA payloads and TS payloads are
 641 |    going to be mostly static.  The SA payload will have the SPI value
 642 |    used in the ESP, but the algorithms are most likely going to be the
 643 |    one and only supported set.  The TS payloads on the initiator end
 644 |    will most likely say from any to any, i.e. full wildcard ranges, or
 645 |    from the local IP to the remote IP.  In the wildcard case the server
 646 |    quite often narrow the range down to the one IP address pair.  Using
 647 |    single IP address pair as a traffic selectors when sending IKE_AUTH
 648 |    will simplify processing as then server will either accept that pair
 649 |    or return error.  If wildcard ranges are used, there is possibility
 650 |    that server narrows the range to some other range than what was
 651 | 
 652 | 
 653 | 
 654 | Kivinen                   Expires April 4, 2013                 [Page 9]
 655 | 

 656 | Internet-Draft                Minimal IKEv2                 October 2012
 657 | 
 658 | 
 659 |    intended.
 660 | 
 661 |    The IKE_AUTH (and IKE_SA_INIT) responses may contain multiple status
 662 |    notification payloads which can be ignored by minimal implementation.
 663 |    There can also be Vendor ID, Certificate, Certificate Request or
 664 |    Configuration payloads, but any payload unknown to minimal
 665 |    implementation can simply be skipped over (response messages cannot
 666 |    have critical unsupported payloads).
 667 | 
 668 |    The exchange above includes N(INITIAL_CONTACT) notification in the
 669 |    request as that is quite commonly sent by the minimal implementation.
 670 |    It indicates to the other end that the initiator does not have any
 671 |    other IKE SAs between them, and if there is any left from previous
 672 |    runs they can be deleted.  As minimal implementation does not delete
 673 |    IKE SAs by sending IKE SA delete, this will help server to clean up
 674 |    leftover state.
 675 | 
 676 |    When using shared secret authentication, the peers are authenticated
 677 |    by having each calculating a MAC over a block of data:
 678 | 
 679 |    For the initiator:
 680 |       AUTH = prf( prf(Shared Secret, "Key Pad for IKEv2"),
 681 |                        <InitiatorSignedOctets>)
 682 |    For the responder:
 683 |       AUTH = prf( prf(Shared Secret, "Key Pad for IKEv2"),
 684 |                        <ResponderSignedOctets>)
 685 | 
 686 |    The string "Key Pad for IKEv2" is 17 ASCII characters without null
 687 |    termination.  The implementation can precalculate the inner prf and
 688 |    only store the output of it.  This is possible because minimal IKEv2
 689 |    implementation usually only supports one PRF.
 690 | 
 691 |    The initiator signs the first message (IKE_SA_INIT request), starting
 692 |    with the first octet of the first SPI in the header and ending with
 693 |    the last octet of the last payload in that first message.  Appended
 694 |    to this (for purposes of computing the signature) are the responder's
 695 |    nonce Nr, and the value prf(SK_pi, IDi').
 696 | 
 697 |    For the responder, the octets to be signed start with the first octet
 698 |    of the first SPI in the header of the second message (IKE_SA_INIT
 699 |    response) and end with the last octet of the last payload in that
 700 |    second message.  Appended to this are the initiator's nonce Ni, and
 701 |    the value prf(SK_pr, IDr').
 702 | 
 703 |    In these calculations, IDi' and IDr' are the entire ID payloads
 704 |    excluding the fixed header and the Ni, and Nr are only the value, not
 705 |    the payload containing it.  Note that neither the nonce Ni/Nr nor the
 706 |    value prf(SK_pr, IDr')/prf(SK_pi, IDi') are transmitted.
 707 | 
 708 | 
 709 | 
 710 | Kivinen                   Expires April 4, 2013                [Page 10]
 711 | 

 712 | Internet-Draft                Minimal IKEv2                 October 2012
 713 | 
 714 | 
 715 |    The initiator's signed octets can be described as:
 716 | 
 717 |    InitiatorSignedOctets = RealMessage1 | NonceRData | MACedIDForI
 718 |    GenIKEHDR = [ four octets 0 if using port 4500 ] | RealIKEHDR
 719 |    RealIKEHDR =  SPIi | SPIr |  . . . | Length
 720 |    RealMessage1 = RealIKEHDR | RestOfMessage1
 721 |    NonceRPayload = PayloadHeader | NonceRData
 722 |    InitiatorIDPayload = PayloadHeader | RestOfInitIDPayload
 723 |    RestOfInitIDPayload = IDType | RESERVED | InitIDData
 724 |    MACedIDForI = prf(SK_pi, RestOfInitIDPayload)
 725 | 
 726 |    The responder's signed octets can be described as:
 727 | 
 728 |    ResponderSignedOctets = RealMessage2 | NonceIData | MACedIDForR
 729 |    GenIKEHDR = [ four octets 0 if using port 4500 ] | RealIKEHDR
 730 |    RealIKEHDR =  SPIi | SPIr |  . . . | Length
 731 |    RealMessage2 = RealIKEHDR | RestOfMessage2
 732 |    NonceIPayload = PayloadHeader | NonceIData
 733 |    ResponderIDPayload = PayloadHeader | RestOfRespIDPayload
 734 |    RestOfRespIDPayload = IDType | RESERVED | RespIDData
 735 |    MACedIDForR = prf(SK_pr, RestOfRespIDPayload)
 736 | 
 737 |    Note that all of the payloads inside the RestOfMessageX are included
 738 |    under the signature, including any payload types not listed in this
 739 |    document.
 740 | 
 741 |    The initiator might also get unauthenticated response back having
 742 |    notification payload with error code inside.  As that error code will
 743 |    be unauthenticated and may be faked, there is no need to do anything
 744 |    for those.  Minimal implementation can simply ignore those errors,
 745 |    and retransmit its request until it times out and if that happens
 746 |    then the IKE SA (and Child SA) creation failed.
 747 | 
 748 |    Responder might also reply with IKE_AUTH response packet which do not
 749 |    contain payloads needed to set up Child SA (SAr2, TSi and TSr), but
 750 |    contains AUTH payload and an error.  As minimal implementation
 751 |    probably do not support multiple SAs nor sending the CREATE_CHILD_SA
 752 |    exchanges the IKE SA is useless for initiator.  It can delete the IKE
 753 |    SA and start over from the beginning (which might fail again if this
 754 |    is configuration error, or it might succeed if this was temporal
 755 |    failure).
 756 | 
 757 | 2.2.  Other Exchanges
 758 | 
 759 |    Minimal implementation MUST be able to reply to INFORMATIONAL request
 760 |    by sending empty response back:
 761 | 
 762 | 
 763 | 
 764 | 
 765 | 
 766 | Kivinen                   Expires April 4, 2013                [Page 11]
 767 | 

 768 | Internet-Draft                Minimal IKEv2                 October 2012
 769 | 
 770 | 
 771 |    Initiator                         Responder
 772 |    -------------------------------------------------------------------
 773 |                       <--  HDR(SPIi=xxx, SPIr=yyy, INFORMATIONAL,
 774 |                                   Flags: none,  Message ID=m),
 775 |                                   SK {...}
 776 | 
 777 |    HDR(SPIi=xxx, SPIr=yyy, INFORMATIONAL,
 778 |        Flags: Initiator | Response,
 779 |        Message ID=m),
 780 |        SK {}  -->
 781 | 
 782 |    Minimal implementation also MUST be able to reply to incoming
 783 |    CREATE_CHILD_SA requests.  Typical implementation will reject the
 784 |    CREATE_CHILD_SA exchanges by sending NO_ADDITIONAL_SAS error notify
 785 |    back:
 786 | 
 787 |    Initiator                         Responder
 788 |    -------------------------------------------------------------------
 789 |                       <--  HDR(SPIi=xxx, SPIy=yyy, CREATE_CHILD_SA,
 790 |                                   Flags: none, Message ID=m),
 791 |                                   SK {...}
 792 | 
 793 |    HDR(SPIi=xxx, SPIr=yyy, CREATE_CHILD_SA,
 794 |        Flags: Initiator | Response, Message ID=m),
 795 |        SK {N(NO_ADDITIONAL_SAS)}  -->
 796 | 
 797 |    Note, that INFORMATIONAL and CREATE_CHILD_SA requests might contain
 798 |    unsupported critical payloads, in which case complient implementation
 799 |    MUST ignore the request, and send response message back having the
 800 |    UNSUPPORTED_CRITICAL_PAYLOAD notification.  That notification payload
 801 |    data contains one-octet payload type of the unsupported critical
 802 |    payload.
 803 | 
 804 | 2.3.  Generating Keying Material
 805 | 
 806 |    Keying material for Child SA created by the IKE_AUTH exchange is
 807 |    generated as follows:
 808 | 
 809 |    KEYMAT = prf+(SK_d, Ni | Nr)
 810 | 
 811 |    Where Ni and Nr are the nonces from the IKE_SA_INIT exchange.
 812 | 
 813 |    A single CHILD_SA negotiation may result in multiple Security
 814 |    Associations.  ESP and AH SAs exist in pairs (one in each direction),
 815 |    so two SAs are created in a single Child SA negotiation for them.
 816 |    The keying material for each Child SA MUST be taken from the expanded
 817 |    KEYMAT using the following rules:
 818 | 
 819 | 
 820 | 
 821 | 
 822 | Kivinen                   Expires April 4, 2013                [Page 12]
 823 | 

 824 | Internet-Draft                Minimal IKEv2                 October 2012
 825 | 
 826 | 
 827 |    o  All keys for SAs carrying data from the initiator to the responder
 828 |       are taken before SAs going from the responder to the initiator.
 829 | 
 830 |    o  If an IPsec protocol requires multiple keys, the order in which
 831 |       they are taken from the SA's keying material needs to be described
 832 |       in the protocol's specification.  For ESP and AH, [IPSECARCH]
 833 |       defines the order, namely: the encryption key (if any) MUST be
 834 |       taken from the first bits and the integrity key (if any) MUST be
 835 |       taken from the remaining bits.
 836 | 
 837 |    Each cryptographic algorithm takes a fixed number of bits of keying
 838 |    material specified as part of the algorithm, or negotiated in SA
 839 |    payloads.
 840 | 
 841 | 
 842 | 
 843 | 
 844 | 
 845 | 
 846 | 
 847 | 
 848 | 
 849 | 
 850 | 
 851 | 
 852 | 
 853 | 
 854 | 
 855 | 
 856 | 
 857 | 
 858 | 
 859 | 
 860 | 
 861 | 
 862 | 
 863 | 
 864 | 
 865 | 
 866 | 
 867 | 
 868 | 
 869 | 
 870 | 
 871 | 
 872 | 
 873 | 
 874 | 
 875 | 
 876 | 
 877 | 
 878 | Kivinen                   Expires April 4, 2013                [Page 13]
 879 | 

 880 | Internet-Draft                Minimal IKEv2                 October 2012
 881 | 
 882 | 
 883 | 3.  Conformance Requirements
 884 | 
 885 |    For an implementation to be called conforming to RFC 5996
 886 |    specification, it MUST be possible to configure it to accept the
 887 |    following:
 888 | 
 889 |    o  Public Key Infrastructure using X.509 (PKIX) Certificates
 890 |       containing and signed by RSA keys of size 1024 or 2048 bits, where
 891 |       the ID passed is any of ID_KEY_ID, ID_FQDN, ID_RFC822_ADDR, or
 892 |       ID_DER_ASN1_DN.
 893 | 
 894 |    o  Shared key authentication where the ID passed is any of ID_KEY_ID,
 895 |       ID_FQDN, or ID_RFC822_ADDR.
 896 | 
 897 |    o  Authentication where the responder is authenticated using PKIX
 898 |       Certificates and the initiator is authenticated using shared key
 899 |       authentication.
 900 | 
 901 |    This document only supports the second bullet, it does not support
 902 |    PKIX certificates at all.  As full RFC5996 responders must also
 903 |    support that shared key authentication, this allows minimal
 904 |    implementation to be able to interoperate with all RFC 5996 compliant
 905 |    implementations.
 906 | 
 907 |    PKIX certificates are left out from the minimal implementation as
 908 |    those would add quite a lot of complexity to the implementation.  The
 909 |    actual code changes needed in the IKEv2 protocol are small, but the
 910 |    certificate validation code would be more complex than the whole
 911 |    minimal IKEv2 implementation itself.  If public key based
 912 |    authentication is needed for scalability reasons, then raw RSA keys
 913 |    would probably be the best compromize (see Appendix B.2).
 914 | 
 915 | 
 916 | 
 917 | 
 918 | 
 919 | 
 920 | 
 921 | 
 922 | 
 923 | 
 924 | 
 925 | 
 926 | 
 927 | 
 928 | 
 929 | 
 930 | 
 931 | 
 932 | 
 933 | 
 934 | Kivinen                   Expires April 4, 2013                [Page 14]
 935 | 

 936 | Internet-Draft                Minimal IKEv2                 October 2012
 937 | 
 938 | 
 939 | 4.  Security Considerations
 940 | 
 941 |    As this implements same protocol as RFC 5996 this means all security
 942 |    considerations from it also apply to this document.
 943 | 
 944 | 
 945 | 
 946 | 
 947 | 
 948 | 
 949 | 
 950 | 
 951 | 
 952 | 
 953 | 
 954 | 
 955 | 
 956 | 
 957 | 
 958 | 
 959 | 
 960 | 
 961 | 
 962 | 
 963 | 
 964 | 
 965 | 
 966 | 
 967 | 
 968 | 
 969 | 
 970 | 
 971 | 
 972 | 
 973 | 
 974 | 
 975 | 
 976 | 
 977 | 
 978 | 
 979 | 
 980 | 
 981 | 
 982 | 
 983 | 
 984 | 
 985 | 
 986 | 
 987 | 
 988 | 
 989 | 
 990 | Kivinen                   Expires April 4, 2013                [Page 15]
 991 | 

 992 | Internet-Draft                Minimal IKEv2                 October 2012
 993 | 
 994 | 
 995 | 5.  IANA Considerations
 996 | 
 997 |    There is no new IANA considerations in this document.
 998 | 
 999 | 
1000 | 
1001 | 
1002 | 
1003 | 
1004 | 
1005 | 
1006 | 
1007 | 
1008 | 
1009 | 
1010 | 
1011 | 
1012 | 
1013 | 
1014 | 
1015 | 
1016 | 
1017 | 
1018 | 
1019 | 
1020 | 
1021 | 
1022 | 
1023 | 
1024 | 
1025 | 
1026 | 
1027 | 
1028 | 
1029 | 
1030 | 
1031 | 
1032 | 
1033 | 
1034 | 
1035 | 
1036 | 
1037 | 
1038 | 
1039 | 
1040 | 
1041 | 
1042 | 
1043 | 
1044 | 
1045 | 
1046 | Kivinen                   Expires April 4, 2013                [Page 16]
1047 | 

1048 | Internet-Draft                Minimal IKEv2                 October 2012
1049 | 
1050 | 
1051 | 6.  Acknowledgements
1052 | 
1053 |    Most of the contents of this document is copied from the RFC 5996.
1054 | 
1055 | 
1056 | 
1057 | 
1058 | 
1059 | 
1060 | 
1061 | 
1062 | 
1063 | 
1064 | 
1065 | 
1066 | 
1067 | 
1068 | 
1069 | 
1070 | 
1071 | 
1072 | 
1073 | 
1074 | 
1075 | 
1076 | 
1077 | 
1078 | 
1079 | 
1080 | 
1081 | 
1082 | 
1083 | 
1084 | 
1085 | 
1086 | 
1087 | 
1088 | 
1089 | 
1090 | 
1091 | 
1092 | 
1093 | 
1094 | 
1095 | 
1096 | 
1097 | 
1098 | 
1099 | 
1100 | 
1101 | 
1102 | Kivinen                   Expires April 4, 2013                [Page 17]
1103 | 

1104 | Internet-Draft                Minimal IKEv2                 October 2012
1105 | 
1106 | 
1107 | 7.  References
1108 | 
1109 | 7.1.  Normative References
1110 | 
1111 |    [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
1112 |               Requirement Levels", BCP 14, RFC 2119, March 1997.
1113 | 
1114 |    [RFC5996]  Kaufman, C., Hoffman, P., Nir, Y., and P. Eronen,
1115 |               "Internet Key Exchange Protocol Version 2 (IKEv2)",
1116 |               RFC 5996, September 2010.
1117 | 
1118 | 7.2.  Informative References
1119 | 
1120 |    [IKEV2IANA]
1121 |               "Internet Key Exchange Version 2 (IKEv2) Parameters",
1122 |               <http://www.iana.org>.
1123 | 
1124 |    [MODES]    National Institute of Standards and Technology, U.S.
1125 |               Department of Commerce, "Recommendation for Block Cipher
1126 |               Modes of Operation", SP 800-38A, 2001.
1127 | 
1128 |    [RFC3447]  Jonsson, J. and B. Kaliski, "Public-Key Cryptography
1129 |               Standards (PKCS) #1: RSA Cryptography Specifications
1130 |               Version 2.1", RFC 3447, February 2003.
1131 | 
1132 |    [RFC5280]  Cooper, D., Santesson, S., Farrell, S., Boeyen, S.,
1133 |               Housley, R., and W. Polk, "Internet X.509 Public Key
1134 |               Infrastructure Certificate and Certificate Revocation List
1135 |               (CRL) Profile", RFC 5280, May 2008.
1136 | 
1137 |    [RSA]      R. Rivest, A. Shamir, and L. Adleman, "A Method for
1138 |               Obtaining Digital Signatures and Public-Key
1139 |               Cryptosystems", February 1978.
1140 | 
1141 | 
1142 | 
1143 | 
1144 | 
1145 | 
1146 | 
1147 | 
1148 | 
1149 | 
1150 | 
1151 | 
1152 | 
1153 | 
1154 | 
1155 | 
1156 | 
1157 | 
1158 | Kivinen                   Expires April 4, 2013                [Page 18]
1159 | 

1160 | Internet-Draft                Minimal IKEv2                 October 2012
1161 | 
1162 | 
1163 | Appendix A.  Header and Payload Formats
1164 | 
1165 |    This appendix describes actual packet payload formats.  This is
1166 |    required to make the document self contained.  The descriptions are
1167 |    mostly copied from the RFC5996 and more information can be found from
1168 |    there.
1169 | 
1170 |    Various payload contains RESERVED fields and those MUST be sent as
1171 |    zero and MUST be ignored on receipt.
1172 | 
1173 |    All multi-octet fields representing integers are laid out in big
1174 |    endian order (also known as "most significant byte first", or
1175 |    "network byte order").
1176 | 
1177 | A.1.  The IKE Header
1178 | 
1179 |    Each IKEv2 message begins with the IKE header, denoted HDR in this
1180 |    document.  Following the header are one or more IKE payloads each
1181 |    identified by a "Next Payload" field in the preceding payload.
1182 |    Payloads are identified in the order in which they appear in an IKE
1183 |    message by looking in the "Next Payload" field in the IKE header, and
1184 |    subsequently according to the "Next Payload" field in the IKE payload
1185 |    itself until a "Next Payload" field of zero indicates that no
1186 |    payloads follow.  If a payload of type "Encrypted" is found, that
1187 |    payload is decrypted and its contents parsed as additional payloads.
1188 |    An Encrypted payload MUST be the last payload in a packet and an
1189 |    Encrypted payload MUST NOT contain another Encrypted payload.
1190 | 
1191 |    The format of the IKE header is shown in Figure 1.
1192 | 
1193 |                         1                   2                   3
1194 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1195 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1196 |    |                       IKE SA Initiator's SPI                  |
1197 |    |                                                               |
1198 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1199 |    |                       IKE SA Responder's SPI                  |
1200 |    |                                                               |
1201 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1202 |    |  Next Payload | MjVer | MnVer | Exchange Type |     Flags     |
1203 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1204 |    |                          Message ID                           |
1205 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1206 |    |                            Length                             |
1207 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1208 | 
1209 |                     Figure 1:  IKE Header Format
1210 | 
1211 | 
1212 | 
1213 | 
1214 | Kivinen                   Expires April 4, 2013                [Page 19]
1215 | 

1216 | Internet-Draft                Minimal IKEv2                 October 2012
1217 | 
1218 | 
1219 |    o  Initiator's SPI (8 octets) - A value chosen by the initiator to
1220 |       identify a unique IKE Security Association.  This value MUST NOT
1221 |       be zero.
1222 | 
1223 |    o  Responder's SPI (8 octets) - A value chosen by the responder to
1224 |       identify a unique IKE Security Association.  This value MUST be
1225 |       zero in the first message of an IKE initial exchange.
1226 | 
1227 |    o  Next Payload (1 octet) - Indicates the type of payload that
1228 |       immediately follows the header.  The format and value of each
1229 |       payload are defined below.
1230 | 
1231 |    o  Major Version (4 bits) - Indicates the major version of the IKE
1232 |       protocol in use.  Implementations based on this version of IKE
1233 |       MUST set the major version to 2 and MUST drop the messages with a
1234 |       higher major version number.
1235 | 
1236 |    o  Minor Version (4 bits) - Indicates the minor version of the IKE
1237 |       protocol in use.  Implementations based on this version of IKE
1238 |       MUST set the minor version to 0.  They MUST ignore the minor
1239 |       version number of received messages.
1240 | 
1241 |    o  Exchange Type (1 octet) - Indicates the type of exchange being
1242 |       used.  This constrains the payloads sent in each message in an
1243 |       exchange.
1244 | 
1245 |       Exchange Type             Value
1246 |       ----------------------------------
1247 |       IKE_SA_INIT               34
1248 |       IKE_AUTH                  35
1249 |       CREATE_CHILD_SA           36
1250 |       INFORMATIONAL             37
1251 | 
1252 |    o  Flags (1 octet) - Indicates specific options that are set for the
1253 |       message.  Presence of options is indicated by the appropriate bit
1254 |       in the flags field being set.  The bits are as follows:
1255 | 
1256 |         +-+-+-+-+-+-+-+-+
1257 |         |X|X|R|V|I|X|X|X|
1258 |         +-+-+-+-+-+-+-+-+
1259 | 
1260 |       In the description below, a bit being 'set' means its value is
1261 |       '1', while 'cleared' means its value is '0'.  'X' bits MUST be
1262 |       cleared when sending and MUST be ignored on receipt.
1263 | 
1264 |       *  R (Response) - This bit indicates that this message is a
1265 |          response to a message containing the same Message ID.  This bit
1266 |          MUST be cleared in all request messages and MUST be set in all
1267 | 
1268 | 
1269 | 
1270 | Kivinen                   Expires April 4, 2013                [Page 20]
1271 | 

1272 | Internet-Draft                Minimal IKEv2                 October 2012
1273 | 
1274 | 
1275 |          responses.  An IKEv2 endpoint MUST NOT generate a response to a
1276 |          message that is marked as being a response.
1277 | 
1278 |       *  V (Version) - This bit indicates that the transmitter is
1279 |          capable of speaking a higher major version number of the
1280 |          protocol than the one indicated in the major version number
1281 |          field.  Implementations of IKEv2 MUST clear this bit when
1282 |          sending and MUST ignore it in incoming messages.
1283 | 
1284 |       *  I (Initiator) - This bit MUST be set in messages sent by the
1285 |          original initiator of the IKE SA and MUST be cleared in
1286 |          messages sent by the original responder.  It is used by the
1287 |          recipient to determine which eight octets of the SPI were
1288 |          generated by the recipient.  This bit changes to reflect who
1289 |          initiated the last rekey of the IKE SA.
1290 | 
1291 |    o  Message ID (4 octets, unsigned integer) - Message identifier used
1292 |       to control retransmission of lost packets and matching of requests
1293 |       and responses.  It is essential to the security of the protocol
1294 |       because it is used to prevent message replay attacks.
1295 | 
1296 |    o  Length (4 octets, unsigned integer) - Length of the total message
1297 |       (header + payloads) in octets.
1298 | 
1299 | A.2.  Generic Payload Header
1300 | 
1301 |    Each IKE payload begins with a generic payload header, shown in
1302 |    Figure 2.  Figures for each payload below will include the generic
1303 |    payload header, but for brevity, the description of each field will
1304 |    be omitted.
1305 | 
1306 |                         1                   2                   3
1307 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1308 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1309 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1310 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1311 | 
1312 |                       Figure 2:  Generic Payload Header
1313 | 
1314 |    The Generic Payload Header fields are defined as follows:
1315 | 
1316 |    o  Next Payload (1 octet) - Identifier for the payload type of the
1317 |       next payload in the message.  If the current payload is the last
1318 |       in the message, then this field will be 0.  This field provides a
1319 |       "chaining" capability whereby additional payloads can be added to
1320 |       a message by appending each one to the end of the message and
1321 |       setting the "Next Payload" field of the preceding payload to
1322 |       indicate the new payload's type.  An Encrypted payload, which must
1323 | 
1324 | 
1325 | 
1326 | Kivinen                   Expires April 4, 2013                [Page 21]
1327 | 

1328 | Internet-Draft                Minimal IKEv2                 October 2012
1329 | 
1330 | 
1331 |       always be the last payload of a message, is an exception.  It
1332 |       contains data structures in the format of additional payloads.  In
1333 |       the header of an Encrypted payload, the Next Payload field is set
1334 |       to the payload type of the first contained payload (instead of 0);
1335 |       conversely, the Next Payload field of the last contained payload
1336 |       is set to zero).  The payload type values needed for minimal
1337 |       implementations are listed here.
1338 | 
1339 |       Next Payload Type                Notation  Value
1340 |       --------------------------------------------------
1341 |       No Next Payload                             0
1342 |       Security Association             SA         33
1343 |       Key Exchange                     KE         34
1344 |       Identification - Initiator       IDi        35
1345 |       Identification - Responder       IDr        36
1346 |       Certificate                      CERT       37
1347 |       Certificate Request              CERTREQ    38
1348 |       Authentication                   AUTH       39
1349 |       Nonce                            Ni, Nr     40
1350 |       Notify                           N          41
1351 |       Delete                           D          42
1352 |       Traffic Selector - Initiator     TSi        44
1353 |       Traffic Selector - Responder     TSr        45
1354 |       Encrypted and Authenticated      SK         46
1355 | 
1356 |    o  Critical (1 bit) - MUST be set to zero if the sender wants the
1357 |       recipient to skip this payload if it does not understand the
1358 |       payload type code in the Next Payload field of the previous
1359 |       payload.  MUST be set to one if the sender wants the recipient to
1360 |       reject this entire message if it does not understand the payload
1361 |       type.  MUST be ignored by the recipient if the recipient
1362 |       understands the payload type code.  MUST be set to zero for
1363 |       payload types defined in this document.  Note that the critical
1364 |       bit applies to the current payload rather than the "next" payload
1365 |       whose type code appears in the first octet.
1366 | 
1367 |    o  Payload Length (2 octets, unsigned integer) - Length in octets of
1368 |       the current payload, including the generic payload header.
1369 | 
1370 | A.3.  Security Association Payload
1371 | 
1372 |    The Security Association payload, denoted SA in this document, is
1373 |    used to negotiate attributes of a Security Association.
1374 | 
1375 |    An SA payload consists of one or more proposals.  Each proposal
1376 |    includes one protocol.  Each protocol contains one or more transforms
1377 |    -- each specifying a cryptographic algorithm.  Each transform
1378 |    contains zero or more attributes (attributes are needed only if the
1379 | 
1380 | 
1381 | 
1382 | Kivinen                   Expires April 4, 2013                [Page 22]
1383 | 

1384 | Internet-Draft                Minimal IKEv2                 October 2012
1385 | 
1386 | 
1387 |    Transform ID does not completely specify the cryptographic algorithm,
1388 |    currently only attribute is key length attribute for variable length
1389 |    ciphers, meaning there is exactly zero or one attribute).
1390 | 
1391 |    The responder MUST choose a single suite, which may be any subset of
1392 |    the SA proposal following the rules below.
1393 | 
1394 |    Each proposal contains one protocol.  If a proposal is accepted, the
1395 |    SA response MUST contain the same protocol.  Each IPsec protocol
1396 |    proposal contains one or more transforms.  Each transform contains a
1397 |    Transform Type.  The accepted cryptographic suite MUST contain
1398 |    exactly one transform of each type included in the proposal.  For
1399 |    example: if an ESP proposal includes transforms ENCR_3DES, ENCR_AES
1400 |    w/keysize 128, ENCR_AES w/keysize 256, AUTH_HMAC_MD5, and
1401 |    AUTH_HMAC_SHA, the accepted suite MUST contain one of the ENCR_
1402 |    transforms and one of the AUTH_ transforms.  Thus, six combinations
1403 |    are acceptable.
1404 | 
1405 |    Minimal implementation can create very simple SA proposal, i.e.
1406 |    include one proposal, which contains exactly one transform for each
1407 |    transform type.  It is important to only include one Diffie-Hellman
1408 |    group in proposal, so there is no need to do INVALID_KE_PAYLOAD
1409 |    processing in responses.
1410 | 
1411 |    When parsing an SA, an implementation MUST check that the total
1412 |    Payload Length is consistent with the payload's internal lengths and
1413 |    counts.  Proposals, Transforms, and Attributes each have their own
1414 |    variable-length encodings.  They are nested such that the Payload
1415 |    Length of an SA includes the combined contents of the SA, Proposal,
1416 |    Transform, and Attribute information.  The length of a Proposal
1417 |    includes the lengths of all Transforms and Attributes it contains.
1418 |    The length of a Transform includes the lengths of all Attributes it
1419 |    contains.
1420 | 
1421 |    Each Proposal/Protocol structure is followed by one or more transform
1422 |    structures.  The number of different transforms is generally
1423 |    determined by the Protocol.  AH generally has two transforms:
1424 |    Extended Sequence Numbers (ESNs) and an integrity check algorithm.
1425 |    ESP generally has three: ESN, an encryption algorithm, and an
1426 |    integrity check algorithm.  IKEv2 generally has four transforms: a
1427 |    Diffie-Hellman group, an integrity check algorithm, a PRF algorithm,
1428 |    and an encryption algorithm.  For each Protocol, the set of
1429 |    permissible transforms is assigned Transform ID numbers, which appear
1430 |    in the header of each transform.
1431 | 
1432 |    If there are multiple transforms with the same Transform Type, the
1433 |    proposal is an OR of those transforms.  If there are multiple
1434 |    transforms with different Transform Types, the proposal is an AND of
1435 | 
1436 | 
1437 | 
1438 | Kivinen                   Expires April 4, 2013                [Page 23]
1439 | 

1440 | Internet-Draft                Minimal IKEv2                 October 2012
1441 | 
1442 | 
1443 |    the different groups.
1444 | 
1445 |    A given transform MAY have one or more Attributes.  Attributes are
1446 |    necessary when the transform can be used in more than one way, as
1447 |    when an encryption algorithm has a variable key size.  The transform
1448 |    would specify the algorithm and the attribute would specify the key
1449 |    size.  To propose alternate values for an attribute (for example,
1450 |    multiple key sizes for the AES encryption algorithm), an
1451 |    implementation MUST include multiple transforms with the same
1452 |    Transform Type each with a single Attribute.
1453 | 
1454 |                         1                   2                   3
1455 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1456 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1457 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1458 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1459 |    |                                                               |
1460 |    ~                          <Proposals>                          ~
1461 |    |                                                               |
1462 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1463 | 
1464 |             Figure 3:  Security Association Payload
1465 | 
1466 |    o  Proposals (variable) - One or more proposal substructures.
1467 | 
1468 | A.3.1.  Proposal Substructure
1469 | 
1470 |                         1                   2                   3
1471 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1472 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1473 |    | 0 (last) or 2 |   RESERVED    |         Proposal Length       |
1474 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1475 |    | Proposal Num  |  Protocol ID  |    SPI Size   |Num  Transforms|
1476 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1477 |    ~                        SPI (variable)                         ~
1478 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1479 |    |                                                               |
1480 |    ~                        <Transforms>                           ~
1481 |    |                                                               |
1482 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1483 | 
1484 |             Figure 4:  Proposal Substructure
1485 | 
1486 |    o  0 (last) or 2 (more) (1 octet) - Specifies whether this is the
1487 |       last Proposal Substructure in the SA.
1488 | 
1489 |    o  Proposal Length (2 octets, unsigned integer) - Length of this
1490 |       proposal, including all transforms and attributes that follow.
1491 | 
1492 | 
1493 | 
1494 | Kivinen                   Expires April 4, 2013                [Page 24]
1495 | 

1496 | Internet-Draft                Minimal IKEv2                 October 2012
1497 | 
1498 | 
1499 |    o  Proposal Num (1 octet) - When a proposal is made, the first
1500 |       proposal in an SA payload MUST be 1, and subsequent proposals MUST
1501 |       be one more than the previous proposal.  When a proposal is
1502 |       accepted, the proposal number in the SA payload MUST match the
1503 |       number on the proposal sent that was accepted.
1504 | 
1505 |    o  Protocol ID (1 octet) - Specifies the IPsec protocol identifier
1506 |       for the current negotiation.
1507 | 
1508 |       Protocol                Protocol ID
1509 |       -----------------------------------
1510 |       IKE                     1
1511 |       AH                      2
1512 |       ESP                     3
1513 | 
1514 |    o  SPI Size (1 octet) - For an initial IKE SA negotiation, this field
1515 |       MUST be zero; the SPI is obtained from the outer header.  During
1516 |       subsequent negotiations, it is equal to the size, in octets, of
1517 |       the SPI of the corresponding protocol (8 for IKE, 4 for ESP and
1518 |       AH).
1519 | 
1520 |    o  Num Transforms (1 octet) - Specifies the number of transforms in
1521 |       this proposal.
1522 | 
1523 |    o  SPI (variable) - The sending entity's SPI.  When the SPI Size
1524 |       field is zero, this field is not present in the Security
1525 |       Association payload.
1526 | 
1527 |    o  Transforms (variable) - One or more transform substructures.
1528 | 
1529 | A.3.2.  Transform Substructure
1530 | 
1531 |                         1                   2                   3
1532 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1533 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1534 |    | 0 (last) or 3 |   RESERVED    |        Transform Length       |
1535 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1536 |    |Transform Type |   RESERVED    |          Transform ID         |
1537 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1538 |    |                                                               |
1539 |    ~                      Transform Attributes                     ~
1540 |    |                                                               |
1541 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1542 | 
1543 |             Figure 5:  Transform Substructure
1544 | 
1545 | 
1546 | 
1547 | 
1548 | 
1549 | 
1550 | Kivinen                   Expires April 4, 2013                [Page 25]
1551 | 

1552 | Internet-Draft                Minimal IKEv2                 October 2012
1553 | 
1554 | 
1555 |    o  0 (last) or 3 (more) (1 octet) - Specifies whether this is the
1556 |       last Transform Substructure in the Proposal.
1557 | 
1558 |    o  Transform Length - The length (in octets) of the Transform
1559 |       Substructure including Header and Attributes.
1560 | 
1561 |    o  Transform Type (1 octet) - The type of transform being specified
1562 |       in this transform.  Different protocols support different
1563 |       Transform Types.  For some protocols, some of the transforms may
1564 |       be optional.  If a transform is optional and the initiator wishes
1565 |       to propose that the transform be omitted, no transform of the
1566 |       given type is included in the proposal.  If the initiator wishes
1567 |       to make use of the transform optional to the responder, it
1568 |       includes a transform substructure with Transform ID = 0 as one of
1569 |       the options.
1570 | 
1571 |    o  Transform ID (2 octets) - The specific instance of the Transform
1572 |       Type being proposed.
1573 | 
1574 |    The relevant Transform Type values are listed below.
1575 | 
1576 |    Description                     Trans.  Used In
1577 |                                    Type
1578 |    ------------------------------------------------------------------
1579 |    Encryption Algorithm (ENCR)     1       IKE and ESP
1580 |    Pseudorandom Function (PRF)     2       IKE
1581 |    Integrity Algorithm (INTEG)     3       IKE, AH, optional in ESP
1582 |    Diffie-Hellman group (D-H)      4       IKE, optional in AH & ESP
1583 |    Extended Sequence Numbers (ESN) 5       AH and ESP
1584 | 
1585 |    For Transform Type 1 (Encryption Algorithm), the relevant Transform
1586 |    IDs are listed below.
1587 | 
1588 |    Name                 Number      Defined In
1589 |    ---------------------------------------------------
1590 |    ENCR_3DES            3           (RFC2451)
1591 |    ENCR_AES_CBC         12          (RFC3602)
1592 | 
1593 |    For Transform Type 2 (Pseudorandom Function), the relevant Transform
1594 |    IDs are listed below.
1595 | 
1596 |    Name                        Number    Defined In
1597 |    ------------------------------------------------------
1598 |    PRF_HMAC_MD5                1         (RFC2104), [MD5]
1599 |    PRF_HMAC_SHA1               2         (RFC2104), [SHA]
1600 | 
1601 |    For Transform Type 3 (Integrity Algorithm), relevant Transform IDs
1602 |    are listed below.
1603 | 
1604 | 
1605 | 
1606 | Kivinen                   Expires April 4, 2013                [Page 26]
1607 | 

1608 | Internet-Draft                Minimal IKEv2                 October 2012
1609 | 
1610 | 
1611 |    Name                 Number   Defined In
1612 |    ----------------------------------------
1613 |    NONE                 0
1614 |    AUTH_HMAC_MD5_96     1        (RFC2403)
1615 |    AUTH_HMAC_SHA1_96    2        (RFC2404)
1616 |    AUTH_AES_XCBC_96     5        (RFC3566)
1617 | 
1618 |    For Transform Type 4 (Diffie-Hellman group), relevant Transform IDs
1619 |    are listed below.
1620 | 
1621 |    Name               Number     Defined In
1622 |    ----------------------------------------
1623 |    NONE               0
1624 |    768-bit MODP       1          Appendix B
1625 |    1024-bit MODP      2          Appendix B
1626 |    1536-bit MODP      5          [ADDGROUP]
1627 |    2048-bit MODP      14         [ADDGROUP]
1628 | 
1629 |    For Transform Type 5 (Extended Sequence Numbers), relevant Transform
1630 |    IDs are listed below.
1631 | 
1632 |    Name                               Number
1633 |    --------------------------------------------
1634 |    No Extended Sequence Numbers       0
1635 |    Extended Sequence Numbers          1
1636 | 
1637 |    Note that an initiator who supports ESNs will usually include two ESN
1638 |    transforms, with values "0" and "1", in its proposals.  A proposal
1639 |    containing a single ESN transform with value "1" means that using
1640 |    normal (non-extended) sequence numbers is not acceptable.
1641 | 
1642 | A.3.3.  Valid Transform Types by Protocol
1643 | 
1644 |    The number and type of transforms that accompany an SA payload are
1645 |    dependent on the protocol in the SA itself.  An SA payload proposing
1646 |    the establishment of an SA has the following mandatory and optional
1647 |    Transform Types.  A compliant implementation MUST understand all
1648 |    mandatory and optional types for each protocol it supports (though it
1649 |    need not accept proposals with unacceptable suites).  A proposal MAY
1650 |    omit the optional types if the only value for them it will accept is
1651 |    NONE.
1652 | 
1653 |    Protocol    Mandatory Types          Optional Types
1654 |    ---------------------------------------------------
1655 |    IKE         ENCR, PRF, INTEG, D-H
1656 |    ESP         ENCR, ESN                INTEG, D-H
1657 |    AH          INTEG, ESN               D-H
1658 | 
1659 | 
1660 | 
1661 | 
1662 | Kivinen                   Expires April 4, 2013                [Page 27]
1663 | 

1664 | Internet-Draft                Minimal IKEv2                 October 2012
1665 | 
1666 | 
1667 | A.3.4.  Transform Attributes
1668 | 
1669 |    Transform type 1 (Encryption Algorithm) transforms might include one
1670 |    transform attribute: Key Length.
1671 | 
1672 |                         1                   2                   3
1673 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1674 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1675 |    |1|       Attribute Type        |        Attribute Value        |
1676 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1677 |                    Figure 6:  Data Attributes
1678 | 
1679 |    o  Attribute Type (15 bits) - Unique identifier for each type of
1680 |       attribute (see below).
1681 | 
1682 |    o  Attribute Value - Value of the attribute associated with the
1683 |       attribute type.
1684 | 
1685 | 
1686 |    Attribute Type         Value
1687 |    ----------------------------
1688 |    Key Length (in bits)   14
1689 | 
1690 |    The Key Length attribute specifies the key length in bits (MUST use
1691 |    network byte order) for certain transforms as follows:
1692 | 
1693 |    o  The Key Length attribute MUST NOT be used with transforms that use
1694 |       a fixed-length key.
1695 | 
1696 |    o  Some transforms specify that the Key Length attribute MUST be
1697 |       always included.  For example ENCR_AES_CBC.
1698 | 
1699 | A.4.  Key Exchange Payload
1700 | 
1701 |                         1                   2                   3
1702 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1703 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1704 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1705 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1706 |    |   Diffie-Hellman Group Num    |           RESERVED            |
1707 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1708 |    |                                                               |
1709 |    ~                       Key Exchange Data                       ~
1710 |    |                                                               |
1711 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1712 | 
1713 |              Figure 7:  Key Exchange Payload Format
1714 | 
1715 | 
1716 | 
1717 | 
1718 | Kivinen                   Expires April 4, 2013                [Page 28]
1719 | 

1720 | Internet-Draft                Minimal IKEv2                 October 2012
1721 | 
1722 | 
1723 |    A Key Exchange payload is constructed by copying one's Diffie-Hellman
1724 |    public value into the "Key Exchange Data" portion of the payload.
1725 |    The length of the Diffie-Hellman public value for modular
1726 |    exponentiation group (MODP) groups MUST be equal to the length of the
1727 |    prime modulus over which the exponentiation was performed, prepending
1728 |    zero bits to the value if necessary.
1729 | 
1730 |    The Diffie-Hellman Group Num identifies the Diffie-Hellman group in
1731 |    which the Key Exchange Data was computed.  This Diffie-Hellman Group
1732 |    Num MUST match a Diffie-Hellman group specified in a proposal in the
1733 |    SA payload that is sent in the same message
1734 | 
1735 | A.5.  Identification Payloads
1736 | 
1737 |    The Identification payloads, denoted IDi and IDr in this document,
1738 |    allow peers to assert an identity to one another.  When using the
1739 |    ID_IPV4_ADDR/ID_IPV6_ADDR identity types in IDi/IDr payloads, IKEv2
1740 |    does not require this address to match the address in the IP header
1741 |    of IKEv2 packets, or anything in the TSi/TSr payloads.  The contents
1742 |    of IDi/IDr are used purely to fetch the policy and authentication
1743 |    data related to the other party.  In minimal implementation it might
1744 |    be easiest to always use KEY_ID type.  This allows the ID payload to
1745 |    be static.  Using IP address has problems in environments where IP
1746 |    addresses are dynamically allocated.
1747 | 
1748 |                         1                   2                   3
1749 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1750 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1751 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1752 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1753 |    |   ID Type     |                 RESERVED                      |
1754 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1755 |    |                                                               |
1756 |    ~                   Identification Data                         ~
1757 |    |                                                               |
1758 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1759 | 
1760 |             Figure 8:  Identification Payload Format
1761 | 
1762 |    o  ID Type (1 octet) - Specifies the type of Identification being
1763 |       used.
1764 | 
1765 |    o  Identification Data (variable length) - Value, as indicated by the
1766 |       Identification Type.  The length of the Identification Data is
1767 |       computed from the size in the ID payload header.
1768 | 
1769 |    The following table lists the assigned semantics for the
1770 |    Identification Type field.
1771 | 
1772 | 
1773 | 
1774 | Kivinen                   Expires April 4, 2013                [Page 29]
1775 | 

1776 | Internet-Draft                Minimal IKEv2                 October 2012
1777 | 
1778 | 
1779 |    ID Type                           Value
1780 |    -------------------------------------------------------------------
1781 |    ID_IPV4_ADDR                        1
1782 |       A single four (4) octet IPv4 address.
1783 | 
1784 |    ID_FQDN                             2
1785 |       A fully-qualified domain name string.  An example of an ID_FQDN
1786 |       is "example.com".  The string MUST NOT contain any terminators
1787 |       (e.g., NULL, CR, etc.). All characters in the ID_FQDN are ASCII;
1788 |       for an "internationalized domain name", the syntax is as defined
1789 |       in [IDNA], for example "xn--tmonesimerkki-bfbb.example.net".
1790 | 
1791 |    ID_RFC822_ADDR                      3
1792 |       A fully-qualified RFC 822 email address string.  An example of a
1793 |       ID_RFC822_ADDR is "jsmith@example.com".  The string MUST NOT
1794 |       contain any terminators.  Because of [EAI], implementations would
1795 |       be wise to treat this field as UTF-8 encoded text, not as
1796 |       pure ASCII.
1797 | 
1798 |    ID_IPV6_ADDR                        5
1799 |       A single sixteen (16) octet IPv6 address.
1800 | 
1801 |    ID_KEY_ID                           11
1802 |       An opaque octet stream that may be used to pass vendor-
1803 |       specific information necessary to do certain proprietary
1804 |       types of identification. Minimal implementation might use
1805 |       this type to send out serial number or similar device
1806 |       specific unique static identification data for the device.
1807 | 
1808 | A.6.  Certificate Payload
1809 | 
1810 |                         1                   2                   3
1811 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1812 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1813 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1814 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1815 |    | Cert Encoding |                                               |
1816 |    +-+-+-+-+-+-+-+-+                                               |
1817 |    ~                       Certificate Data                        ~
1818 |    |                                                               |
1819 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1820 | 
1821 |              Figure 9:  Certificate Payload Format
1822 | 
1823 |    o  Certificate Encoding (1 octet) - This field indicates the type of
1824 |       certificate or certificate-related information contained in the
1825 |       Certificate Data field.
1826 | 
1827 | 
1828 | 
1829 | 
1830 | Kivinen                   Expires April 4, 2013                [Page 30]
1831 | 

1832 | Internet-Draft                Minimal IKEv2                 October 2012
1833 | 
1834 | 
1835 |       Certificate Encoding                 Value
1836 |       ----------------------------------------------------
1837 |       X.509 Certificate - Signature        4
1838 |       Raw RSA Key                          11
1839 | 
1840 |    o  Certificate Data (variable length) - Actual encoding of
1841 |       certificate data.  The type of certificate is indicated by the
1842 |       Certificate Encoding field.
1843 | 
1844 |    The syntax of the types above are:
1845 | 
1846 |    o  "X.509 Certificate - Signature" contains a DER-encoded X.509
1847 |       certificate whose public key is used to validate the sender's AUTH
1848 |       payload.  Note that with this encoding, if a chain of certificates
1849 |       needs to be sent, multiple CERT payloads are used, only the first
1850 |       of which holds the public key used to validate the sender's AUTH
1851 |       payload.
1852 | 
1853 |    o  "Raw RSA Key" contains a PKCS #1 encoded RSA key, that is, a DER-
1854 |       encoded RSAPublicKey structure (see [RSA] and [RFC3447]).
1855 | 
1856 | A.7.  Certificate Request Payload
1857 | 
1858 |                         1                   2                   3
1859 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1860 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1861 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1862 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1863 |    | Cert Encoding |                                               |
1864 |    +-+-+-+-+-+-+-+-+                                               |
1865 |    ~                    Certification Authority                    ~
1866 |    |                                                               |
1867 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1868 | 
1869 |          Figure 10:  Certificate Request Payload Format
1870 | 
1871 |    o  Certificate Encoding (1 octet) - Contains an encoding of the type
1872 |       or format of certificate requested.
1873 | 
1874 |    o  Certification Authority (variable length) - Contains an encoding
1875 |       of an acceptable certification authority for the type of
1876 |       certificate requested.
1877 | 
1878 |    The Certificate Encoding field has the same values as those defined
1879 |    certificate payload.  The Certification Authority field contains an
1880 |    indicator of trusted authorities for this certificate type.  The
1881 |    Certification Authority value is a concatenated list of SHA-1 hashes
1882 |    of the public keys of trusted Certification Authorities (CAs).  Each
1883 | 
1884 | 
1885 | 
1886 | Kivinen                   Expires April 4, 2013                [Page 31]
1887 | 

1888 | Internet-Draft                Minimal IKEv2                 October 2012
1889 | 
1890 | 
1891 |    is encoded as the SHA-1 hash of the Subject Public Key Info element
1892 |    (see section 4.1.2.7 of [RFC5280]) from each Trust Anchor
1893 |    certificate.  The 20-octet hashes are concatenated and included with
1894 |    no other formatting.
1895 | 
1896 | A.8.  Authentication Payload
1897 | 
1898 |                         1                   2                   3
1899 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1900 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1901 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1902 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1903 |    | Auth Method   |                RESERVED                       |
1904 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1905 |    |                                                               |
1906 |    ~                      Authentication Data                      ~
1907 |    |                                                               |
1908 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1909 | 
1910 |               Figure 11:  Authentication Payload Format
1911 | 
1912 |    o  Auth Method (1 octet) - Specifies the method of authentication
1913 |       used.
1914 | 
1915 |    Mechanism                              Value
1916 |    -----------------------------------------------------------------
1917 |    RSA Digital Signature                  1
1918 |       Using an RSA private key with RSASSA-PKCS1-v1_5 signature
1919 |       scheme specified in [PKCS1], see [RFC5996] section 2.15 for
1920 |       details.
1921 | 
1922 |    Shared Key Message Integrity Code      2
1923 |       Computed as specified earlier using the shared key associated
1924 |       with the identity in the ID payload and the negotiated PRF.
1925 | 
1926 |    DSS Digital Signature                  3
1927 |       Using a DSS private key (see [DSS]) over a SHA-1 hash, see
1928 |       [RFC5996] Section 2.15 for details.
1929 | 
1930 |    o  Authentication Data (variable length) - see Section 2.1.
1931 | 
1932 | 
1933 | 
1934 | 
1935 | 
1936 | 
1937 | 
1938 | 
1939 | 
1940 | 
1941 | 
1942 | Kivinen                   Expires April 4, 2013                [Page 32]
1943 | 

1944 | Internet-Draft                Minimal IKEv2                 October 2012
1945 | 
1946 | 
1947 | A.9.  Nonce Payload
1948 | 
1949 |                         1                   2                   3
1950 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1951 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1952 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1953 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1954 |    |                                                               |
1955 |    ~                            Nonce Data                         ~
1956 |    |                                                               |
1957 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1958 | 
1959 |                 Figure 12:  Nonce Payload Format
1960 | 
1961 |    o  Nonce Data (variable length) - Contains the random data generated
1962 |       by the transmitting entity.
1963 | 
1964 |    The size of the Nonce Data MUST be between 16 and 256 octets,
1965 |    inclusive.  Nonce values MUST NOT be reused.
1966 | 
1967 | A.10.  Notify Payload
1968 | 
1969 |    The Notify payload, denoted N in this document, is used to transmit
1970 |    informational data, such as error conditions and state transitions,
1971 |    to an IKE peer.  A Notify payload may appear in a response message
1972 |    (usually specifying why a request was rejected), in an INFORMATIONAL
1973 |    Exchange (to report an error not in an IKE request), or in any other
1974 |    message to indicate sender capabilities or to modify the meaning of
1975 |    the request.
1976 | 
1977 |                         1                   2                   3
1978 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1979 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1980 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
1981 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1982 |    |  Protocol ID  |   SPI Size    |      Notify Message Type      |
1983 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1984 |    |                                                               |
1985 |    ~                Security Parameter Index (SPI)                 ~
1986 |    |                                                               |
1987 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1988 |    |                                                               |
1989 |    ~                       Notification Data                       ~
1990 |    |                                                               |
1991 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1992 | 
1993 |             Figure 13:  Notify Payload Format
1994 | 
1995 | 
1996 | 
1997 | 
1998 | Kivinen                   Expires April 4, 2013                [Page 33]
1999 | 

2000 | Internet-Draft                Minimal IKEv2                 October 2012
2001 | 
2002 | 
2003 |    o  Protocol ID (1 octet) - If this notification concerns an existing
2004 |       SA whose SPI is given in the SPI field, this field indicates the
2005 |       type of that SA.  If the SPI field is empty, this field MUST be
2006 |       sent as zero and MUST be ignored on receipt.
2007 | 
2008 |    o  SPI Size (1 octet) - Length in octets of the SPI as defined by the
2009 |       IPsec protocol ID or zero if no SPI is applicable.  For a
2010 |       notification concerning the IKE SA, the SPI Size MUST be zero and
2011 |       the field must be empty.
2012 | 
2013 |    o  Notify Message Type (2 octets) - Specifies the type of
2014 |       notification message.
2015 | 
2016 |    o  SPI (variable length) - Security Parameter Index.
2017 | 
2018 |    o  Notification Data (variable length) - Status or error data
2019 |       transmitted in addition to the Notify Message Type.  Values for
2020 |       this field are type specific.
2021 | 
2022 | A.10.1.  Notify Message Types
2023 | 
2024 |    Notification information can be error messages specifying why an SA
2025 |    could not be established.  It can also be status data that a process
2026 |    managing an SA database wishes to communicate with a peer process.
2027 | 
2028 |    Types in the range 0 - 16383 are intended for reporting errors.  An
2029 |    implementation receiving a Notify payload with one of these types
2030 |    that it does not recognize in a response MUST assume that the
2031 |    corresponding request has failed entirely.  Unrecognized error types
2032 |    in a request and status types in a request or response MUST be
2033 |    ignored, and they should be logged.
2034 | 
2035 |    Notify payloads with status types MAY be added to any message and
2036 |    MUST be ignored if not recognized.  They are intended to indicate
2037 |    capabilities, and as part of SA negotiation, are used to negotiate
2038 |    non-cryptographic parameters.
2039 | 
2040 | 
2041 | 
2042 | 
2043 | 
2044 | 
2045 | 
2046 | 
2047 | 
2048 | 
2049 | 
2050 | 
2051 | 
2052 | 
2053 | 
2054 | Kivinen                   Expires April 4, 2013                [Page 34]
2055 | 

2056 | Internet-Draft                Minimal IKEv2                 October 2012
2057 | 
2058 | 
2059 |    NOTIFY messages: error types              Value
2060 |    -------------------------------------------------------------------
2061 |    UNSUPPORTED_CRITICAL_PAYLOAD              1
2062 |        Indicates that the one-octet payload type included in the
2063 |        Notification Data field is unknown.
2064 | 
2065 |    INVALID_SYNTAX                            7
2066 |        Indicates the IKE message that was received was invalid because
2067 |        some type, length, or value was out of range or because the
2068 |        request was rejected for policy reasons.  To avoid a DoS
2069 |        attack using forged messages, this status may only be
2070 |        returned for and in an encrypted packet if the Message ID and
2071 |        cryptographic checksum were valid.  To avoid leaking information
2072 |        to someone probing a node, this status MUST be sent in response
2073 |        to any error not covered by one of the other status types.
2074 |        To aid debugging, more detailed error information should be
2075 |        written to a console or log.
2076 | 
2077 |    NO_PROPOSAL_CHOSEN                       14
2078 |        None of the proposed crypto suites was acceptable.  This can be
2079 |        sent in any case where the offered proposals are not acceptable
2080 |        for the responder.
2081 | 
2082 |    NO_ADDITIONAL_SAS                        35
2083 |        Specifies that the node is unwilling to accept any more Child
2084 |        SAs.
2085 | 
2086 | 
2087 | 
2088 |    NOTIFY messages: status types            Value
2089 |    -------------------------------------------------------------------
2090 |    INITIAL_CONTACT                          16384
2091 |        Asserts that this IKE SA is the only IKE SA currently active
2092 |        between the authenticated identities.
2093 | 
2094 | 
2095 | A.11.  Traffic Selector Payload
2096 | 
2097 |    Traffic Selector (TS) payloads allow endpoints to communicate some of
2098 |    the information from their SPD to their peers.  TS payloads specify
2099 |    the selection criteria for packets that will be forwarded over the
2100 |    newly set up SA.
2101 | 
2102 | 
2103 | 
2104 | 
2105 | 
2106 | 
2107 | 
2108 | 
2109 | 
2110 | Kivinen                   Expires April 4, 2013                [Page 35]
2111 | 

2112 | Internet-Draft                Minimal IKEv2                 October 2012
2113 | 
2114 | 
2115 |                         1                   2                   3
2116 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2117 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2118 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
2119 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2120 |    | Number of TSs |                 RESERVED                      |
2121 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2122 |    |                                                               |
2123 |    ~                       <Traffic Selectors>                     ~
2124 |    |                                                               |
2125 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2126 | 
2127 |             Figure 14:  Traffic Selectors Payload Format
2128 | 
2129 |    o  Number of TSs (1 octet) - Number of Traffic Selectors being
2130 |       provided.
2131 | 
2132 |    o  Traffic Selectors (variable length) - One or more individual
2133 |       Traffic Selectors.
2134 | 
2135 |    The length of the Traffic Selector payload includes the TS header and
2136 |    all the Traffic Selectors.
2137 | 
2138 |    There is no requirement that TSi and TSr contain the same number of
2139 |    individual Traffic Selectors.  Thus, they are interpreted as follows:
2140 |    a packet matches a given TSi/TSr if it matches at least one of the
2141 |    individual selectors in TSi, and at least one of the individual
2142 |    selectors in TSr.
2143 | 
2144 |    Two TS payloads appear in each of the messages in the exchange that
2145 |    creates a Child SA pair.  Each TS payload contains one or more
2146 |    Traffic Selectors.  Each Traffic Selector consists of an address
2147 |    range (IPv4 or IPv6), a port range, and an IP protocol ID.
2148 | 
2149 |    The first of the two TS payloads is known as TSi (Traffic Selector-
2150 |    initiator).  The second is known as TSr (Traffic Selector-responder).
2151 |    TSi specifies the source address of traffic forwarded from (or the
2152 |    destination address of traffic forwarded to) the initiator of the
2153 |    Child SA pair.  TSr specifies the destination address of the traffic
2154 |    forwarded to (or the source address of the traffic forwarded from)
2155 |    the responder of the Child SA pair.
2156 | 
2157 |    IKEv2 allows the responder to choose a subset of the traffic proposed
2158 |    by the initiator.
2159 | 
2160 |    When the responder chooses a subset of the traffic proposed by the
2161 |    initiator, it narrows the Traffic Selectors to some subset of the
2162 |    initiator's proposal (provided the set does not become the null set).
2163 | 
2164 | 
2165 | 
2166 | Kivinen                   Expires April 4, 2013                [Page 36]
2167 | 

2168 | Internet-Draft                Minimal IKEv2                 October 2012
2169 | 
2170 | 
2171 |    If the type of Traffic Selector proposed is unknown, the responder
2172 |    ignores that Traffic Selector, so that the unknown type is not
2173 |    returned in the narrowed set.
2174 | 
2175 |    To enable the responder to choose the appropriate range, if the
2176 |    initiator has requested the SA due to a data packet, the initiator
2177 |    SHOULD include as the first Traffic Selector in each of TSi and TSr a
2178 |    very specific Traffic Selector including the addresses in the packet
2179 |    triggering the request.  If the initiator creates the Child SA pair
2180 |    not in response to an arriving packet, but rather, say, upon startup,
2181 |    then there may be no specific addresses the initiator prefers for the
2182 |    initial tunnel over any other.  In that case, the first values in TSi
2183 |    and TSr can be ranges rather than specific values.
2184 | 
2185 |    As minimal implementations might only support one SA, the traffic
2186 |    selectors will usually be from initiator's IP address to responders
2187 |    IP address (i.e. no port or protocol selectors and only one range).
2188 | 
2189 | A.11.1.  Traffic Selector
2190 | 
2191 |                         1                   2                   3
2192 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2193 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2194 |    |   TS Type     |IP Protocol ID |       Selector Length         |
2195 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2196 |    |           Start Port          |           End Port            |
2197 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2198 |    |                                                               |
2199 |    ~                         Starting Address                      ~
2200 |    |                                                               |
2201 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2202 |    |                                                               |
2203 |    ~                         Ending Address                        ~
2204 |    |                                                               |
2205 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2206 | 
2207 |                Figure 15: Traffic Selector
2208 | 
2209 |    o  TS Type (one octet) - Specifies the type of Traffic Selector.
2210 | 
2211 |    o  IP protocol ID (1 octet) - Value specifying an associated IP
2212 |       protocol ID (such as UDP, TCP, and ICMP).  A value of zero means
2213 |       that the protocol ID is not relevant to this Traffic Selector --
2214 |       the SA can carry all protocols.
2215 | 
2216 |    o  Selector Length - Specifies the length of this Traffic Selector
2217 |       substructure including the header.
2218 | 
2219 | 
2220 | 
2221 | 
2222 | Kivinen                   Expires April 4, 2013                [Page 37]
2223 | 

2224 | Internet-Draft                Minimal IKEv2                 October 2012
2225 | 
2226 | 
2227 |    o  Start Port (2 octets, unsigned integer) - Value specifying the
2228 |       smallest port number allowed by this Traffic Selector.  For
2229 |       protocols for which port is undefined (including protocol 0), or
2230 |       if all ports are allowed, this field MUST be zero.
2231 | 
2232 |    o  End Port (2 octets, unsigned integer) - Value specifying the
2233 |       largest port number allowed by this Traffic Selector.  For
2234 |       protocols for which port is undefined (including protocol 0), or
2235 |       if all ports are allowed, this field MUST be 65535.
2236 | 
2237 |    o  Starting Address - The smallest address included in this Traffic
2238 |       Selector (length determined by TS Type).
2239 | 
2240 |    o  Ending Address - The largest address included in this Traffic
2241 |       Selector (length determined by TS Type).
2242 | 
2243 |    The following table lists values for the Traffic Selector Type field
2244 |    and the corresponding Address Selector Data.
2245 | 
2246 |    TS Type                            Value
2247 |    -------------------------------------------------------------------
2248 |    TS_IPV4_ADDR_RANGE                  7
2249 | 
2250 |        A range of IPv4 addresses, represented by two four-octet
2251 |        values.  The first value is the beginning IPv4 address
2252 |        (inclusive) and the second value is the ending IPv4 address
2253 |        (inclusive).  All addresses falling between the two specified
2254 |        addresses are considered to be within the list.
2255 | 
2256 |    TS_IPV6_ADDR_RANGE                  8
2257 | 
2258 |        A range of IPv6 addresses, represented by two sixteen-octet
2259 |        values.  The first value is the beginning IPv6 address
2260 |        (inclusive) and the second value is the ending IPv6 address
2261 |        (inclusive).  All addresses falling between the two specified
2262 |        addresses are considered to be within the list.
2263 | 
2264 | A.12.  Encrypted Payload
2265 | 
2266 |    The Encrypted payload, denoted SK{...} in this document, contains
2267 |    other payloads in encrypted form.
2268 | 
2269 | 
2270 | 
2271 | 
2272 | 
2273 | 
2274 | 
2275 | 
2276 | 
2277 | 
2278 | Kivinen                   Expires April 4, 2013                [Page 38]
2279 | 

2280 | Internet-Draft                Minimal IKEv2                 October 2012
2281 | 
2282 | 
2283 |                         1                   2                   3
2284 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2285 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2286 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
2287 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2288 |    |                     Initialization Vector                     |
2289 |    |         (length is block size for encryption algorithm)       |
2290 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2291 |    ~                    Encrypted IKE Payloads                     ~
2292 |    +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2293 |    |               |             Padding (0-255 octets)            |
2294 |    +-+-+-+-+-+-+-+-+                               +-+-+-+-+-+-+-+-+
2295 |    |                                               |  Pad Length   |
2296 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2297 |    ~                    Integrity Checksum Data                    ~
2298 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2299 | 
2300 |             Figure 16:  Encrypted Payload Format
2301 | 
2302 |    o  Next Payload - The payload type of the first embedded payload.
2303 |       Note that this is an exception in the standard header format,
2304 |       since the Encrypted payload is the last payload in the message and
2305 |       therefore the Next Payload field would normally be zero.  But
2306 |       because the content of this payload is embedded payloads and there
2307 |       was no natural place to put the type of the first one, that type
2308 |       is placed here.
2309 | 
2310 |    o  Payload Length - Includes the lengths of the header,
2311 |       initialization vector (IV), Encrypted IKE payloads, Padding, Pad
2312 |       Length, and Integrity Checksum Data.
2313 | 
2314 |    o  Initialization Vector - For CBC mode ciphers, the length of the
2315 |       initialization vector (IV) is equal to the block length of the
2316 |       underlying encryption algorithm.  Senders MUST select a new
2317 |       unpredictable IV for every message; recipients MUST accept any
2318 |       value.  The reader is encouraged to consult [MODES] for advice on
2319 |       IV generation.  In particular, using the final ciphertext block of
2320 |       the previous message is not considered unpredictable.  For modes
2321 |       other than CBC, the IV format and processing is specified in the
2322 |       document specifying the encryption algorithm and mode.
2323 | 
2324 |    o  IKE payloads are as specified earlier in this section.  This field
2325 |       is encrypted with the negotiated cipher.
2326 | 
2327 |    o  Padding MAY contain any value chosen by the sender, and MUST have
2328 |       a length that makes the combination of the payloads, the Padding,
2329 |       and the Pad Length to be a multiple of the encryption block size.
2330 |       This field is encrypted with the negotiated cipher.
2331 | 
2332 | 
2333 | 
2334 | Kivinen                   Expires April 4, 2013                [Page 39]
2335 | 

2336 | Internet-Draft                Minimal IKEv2                 October 2012
2337 | 
2338 | 
2339 |    o  Pad Length is the length of the Padding field.  The sender SHOULD
2340 |       set the Pad Length to the minimum value that makes the combination
2341 |       of the payloads, the Padding, and the Pad Length a multiple of the
2342 |       block size, but the recipient MUST accept any length that results
2343 |       in proper alignment.  This field is encrypted with the negotiated
2344 |       cipher.
2345 | 
2346 |    o  Integrity Checksum Data is the cryptographic checksum of the
2347 |       entire message starting with the Fixed IKE header through the Pad
2348 |       Length.  The checksum MUST be computed over the encrypted message.
2349 |       Its length is determined by the integrity algorithm negotiated.
2350 | 
2351 | 
2352 | 
2353 | 
2354 | 
2355 | 
2356 | 
2357 | 
2358 | 
2359 | 
2360 | 
2361 | 
2362 | 
2363 | 
2364 | 
2365 | 
2366 | 
2367 | 
2368 | 
2369 | 
2370 | 
2371 | 
2372 | 
2373 | 
2374 | 
2375 | 
2376 | 
2377 | 
2378 | 
2379 | 
2380 | 
2381 | 
2382 | 
2383 | 
2384 | 
2385 | 
2386 | 
2387 | 
2388 | 
2389 | 
2390 | Kivinen                   Expires April 4, 2013                [Page 40]
2391 | 

2392 | Internet-Draft                Minimal IKEv2                 October 2012
2393 | 
2394 | 
2395 | Appendix B.  Useful Optional Features
2396 | 
2397 |    There are some optional features of IKEv2, which might be useful for
2398 |    minimal implementations in some scenarios.  Such features include Raw
2399 |    RSA keys authentication, and sending IKE SA delete notification.
2400 | 
2401 | B.1.  IKE SA Delete Notification
2402 | 
2403 |    In some scenarios the minimal implementation device creates IKE SA,
2404 |    sends one or few packets, perhaps gets some packets back, and then
2405 |    device goes back to sleep forgetting the IKE SA.  In such scenarios
2406 |    it would be nice for the minimal implementation to send the IKE SA
2407 |    delete notification to tell the other end that the IKE SA is going
2408 |    away, so it can free the resources.
2409 | 
2410 |    Deleting the IKE SA can be done using by sending one packet with
2411 |    fixed Message ID, and with only one payload inside the encrypted
2412 |    payload.  The other end will send back an empty response:
2413 | 
2414 |    Initiator                         Responder
2415 |    -------------------------------------------------------------------
2416 |    HDR(SPIi=xxx, SPIr=yyy, INFORMATIONAL,
2417 |        Flags: Initiator, Message ID=2),
2418 |        SK {D}  -->
2419 | 
2420 |                       <--  HDR(SPIi=xxx, SPIr=yyy, INFORMATIONAL,
2421 |                                Flags: Response, Message ID=2),
2422 |                                SK {}
2423 | 
2424 |    The delete payload format is:
2425 | 
2426 |                         1                   2                   3
2427 |     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2428 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2429 |    | Next Payload  |C|  RESERVED   |         Payload Length        |
2430 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2431 |    | Protocol ID   |   SPI Size    |          Num of SPIs          |
2432 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2433 |    |                                                               |
2434 |    ~               Security Parameter Index(es) (SPI)              ~
2435 |    |                                                               |
2436 |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2437 | 
2438 |                Figure 17:  Delete Payload Format
2439 | 
2440 |    o  Protocol ID (1 octet) - Must be 1 for an IKE SA.
2441 | 
2442 | 
2443 | 
2444 | 
2445 | 
2446 | Kivinen                   Expires April 4, 2013                [Page 41]
2447 | 

2448 | Internet-Draft                Minimal IKEv2                 October 2012
2449 | 
2450 | 
2451 |    o  SPI Size (1 octet) - Length in octets of the SPI as defined by the
2452 |       protocol ID.  It MUST be zero for IKE (SPI is in message header).
2453 | 
2454 |    o  Num of SPIs (2 octets, unsigned integer) - The number of SPIs
2455 |       contained in the Delete payload.  This MUST be zero for IKE.
2456 | 
2457 |    o  Security Parameter Index(es) (variable length) - Identifies the
2458 |       specific Security Association(s) to delete.  The length of this
2459 |       field is determined by the SPI Size and Num of SPIs fields.  This
2460 |       field is empty for the IKE SA delete.
2461 | 
2462 | B.2.  Raw RSA keys
2463 | 
2464 |    In some scenarios the shared secret authentication is not safe
2465 |    enough, as anybody who knows the secret can impersonate himself of
2466 |    being the server.  If the shared secret is printed on the side of the
2467 |    device, then anybody who gets physical access to the device can read
2468 |    it.  In such environments public key authentication allows stronger
2469 |    authentication with minimal operational overhead.  Certificate
2470 |    support is quite complex, and minimal implementations do not usually
2471 |    have need for them.  Using Raw RSA keys is much simpler, and it
2472 |    allows similar scalability than certificates.  The fingerprint of the
2473 |    Raw RSA key can still be distributed by for example printing it on
2474 |    the side of the device allowing similar setup than using shared
2475 |    secret.
2476 | 
2477 |    Raw RSA keys can also be used in leap of faith or baby duck style
2478 |    initial setup, where the device imprints itself to the first device
2479 |    it sees when it first time boots up.  After that initial connection
2480 |    it stores the fingerprint of the Raw RSA key of the server to its own
2481 |    configuration and verifies that it never changes (unless reset to
2482 |    factory setting or similar command is issued).
2483 | 
2484 |    This changes the initial IKE_AUTH payloads as follows:
2485 | 
2486 |    Initiator                         Responder
2487 |    -------------------------------------------------------------------
2488 |    HDR(SPIi=xxx, SPIr=yyy, IKE_AUTH,
2489 |        Flags: Initiator, Message ID=1),
2490 |        SK {IDi, CERT, AUTH, SAi2, TSi, TSr,
2491 |            N(INITIAL_CONTACT)}  -->
2492 | 
2493 |                      <--  HDR(SPIi=xxx, SPIr=yyy, IKE_AUTH, Flags:
2494 |                                  Response, Message ID=1),
2495 |                                  SK {IDr, CERT, AUTH, SAr2, TSi, TSr}
2496 | 
2497 |    The CERT payloads contains the Raw RSA keys used the sign the hash of
2498 |    the InitiatorSignedOctects/ResponderSignedOctects when generating
2499 | 
2500 | 
2501 | 
2502 | Kivinen                   Expires April 4, 2013                [Page 42]
2503 | 

2504 | Internet-Draft                Minimal IKEv2                 October 2012
2505 | 
2506 | 
2507 |    AUTH payload.  Minimal implementations should use SHA-1 as the hash
2508 |    function as that is the SHOULD support algorithm specified in the
2509 |    RFC5996, so it is the most likely one that is supported by all
2510 |    devices.
2511 | 
2512 | 
2513 | 
2514 | 
2515 | 
2516 | 
2517 | 
2518 | 
2519 | 
2520 | 
2521 | 
2522 | 
2523 | 
2524 | 
2525 | 
2526 | 
2527 | 
2528 | 
2529 | 
2530 | 
2531 | 
2532 | 
2533 | 
2534 | 
2535 | 
2536 | 
2537 | 
2538 | 
2539 | 
2540 | 
2541 | 
2542 | 
2543 | 
2544 | 
2545 | 
2546 | 
2547 | 
2548 | 
2549 | 
2550 | 
2551 | 
2552 | 
2553 | 
2554 | 
2555 | 
2556 | 
2557 | 
2558 | Kivinen                   Expires April 4, 2013                [Page 43]
2559 | 

2560 | Internet-Draft                Minimal IKEv2                 October 2012
2561 | 
2562 | 
2563 | Author's Address
2564 | 
2565 |    Tero Kivinen
2566 |    AuthenTec
2567 |    Eerikinkatu 28
2568 |    HELSINKI  FI-00180
2569 |    FI
2570 | 
2571 |    Email: kivinen@iki.fi
2572 | 
2573 | 
2574 | 
2575 | 
2576 | 
2577 | 
2578 | 
2579 | 
2580 | 
2581 | 
2582 | 
2583 | 
2584 | 
2585 | 
2586 | 
2587 | 
2588 | 
2589 | 
2590 | 
2591 | 
2592 | 
2593 | 
2594 | 
2595 | 
2596 | 
2597 | 
2598 | 
2599 | 
2600 | 
2601 | 
2602 | 
2603 | 
2604 | 
2605 | 
2606 | 
2607 | 
2608 | 
2609 | 
2610 | 
2611 | 
2612 | 
2613 | 
2614 | Kivinen                   Expires April 4, 2013                [Page 44]
2615 | 
2616 | 

2617 | Html markup produced by rfcmarkup 1.104, available from 2618 | http://tools.ietf.org/tools/rfcmarkup/ 2619 | 2620 | 2621 | -------------------------------------------------------------------------------- /ike/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['payloads', 'const', 'proposal', 'protocol', 'util'] 2 | __version__ = (0, 1, 1) 3 | -------------------------------------------------------------------------------- /ike/const.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013-2014 Kimmo Parviainen-Jalanko. 4 | # 5 | 6 | # Constants for IKEv2 RFC5996 7 | # http://tools.ietf.org/html/rfc5996 8 | from enum import IntEnum 9 | 10 | import struct 11 | from . util import dh 12 | 13 | __author__ = 'kimvais' 14 | 15 | IKE_VERSION = (2 << 4 | 0) # Major << 4 | Minor 16 | 17 | # iSPI, rSPI, NextPayload, (MjVer, MnVer), ExchangeType, Flags, MessageID, Len 18 | IKE_HEADER = struct.Struct('!2Q4B2L') 19 | 20 | class ExchangeType(IntEnum): 21 | IKE_SA_INIT = 34 22 | IKE_AUTH = 35 23 | CREATE_CHILD_SA = 36 24 | INFORMATIONAL = 37 25 | 26 | IKE_HDR_FLAGS = dict( 27 | R=0b00100000, 28 | I=0b00001000 29 | ) 30 | 31 | PAYLOAD_HEADER = struct.Struct( 32 | '!2BH') # Next Payload, Flags (Critical bit), Len 33 | 34 | PROPOSAL_STRUCT = struct.Struct('!2BH4B') 35 | # Last(0) or 2, Reserved, Proposal Length, Num, Protocol ID, SPI Size, Num transforms 36 | 37 | TRANSFORM_STRUCT = struct.Struct('!2BH2BH') 38 | # Last(0) or 3, Reserved, Transform Length, Transform type, Reserver, Transform ID 39 | 40 | # ENCR=1, # Encryption (IKE and ESP) 41 | # PRF=2, # Pseudo-random function (IKE) 42 | # INTEG=3, # Integrity (IKE, Optional for ESP (AH - not supported)) 43 | # DH=4, # Diffie-Hellman group 44 | # ESN=5, # Extended sequence numbers. 45 | 46 | TRANSFORMS = dict( 47 | AUTH_AES_XCBC_96=(3, 5), # RFC 4307 48 | AUTH_HMAC_SHA1_96=(3, 2), # RFC 4307 49 | AUTH_HMAC_SHA2_256_128=(3, 12), # RFC 4868 50 | AUTH_HMAC_SHA2_384_192=(3, 13), # RFC 4868 51 | AUTH_HMAC_SHA2_512_256=(3, 14), # RFC 4868 52 | ENCR_AES_CBC=(1, 12), # RFC 4307 53 | ENCR_AES_CTR=(1, 13), # RFC 4307 54 | ENCR_CAMELLIA_CBC=(1, 23), # RFC 5529 55 | ENCR_CAMELLIA_CTR=(1, 24), # RFC 5529 56 | PRF_AES128_CBC=(2, 4), # RFC 4307 57 | PRF_HMAC_SHA1=(2, 2), # RFC 4307 58 | PRF_HMAC_SHA2_256=(2, 5), # RFC 4868 59 | PRF_HMAC_SHA2_384=(2, 6), # RFC 4868 60 | PRF_HMAC_SHA2_512=(2, 7), # RFC 4868 61 | ESN=(5, 1) # RFC 5996 62 | ) 63 | for group_id in dh.PRIMES.keys(): 64 | TRANSFORMS['DH_GROUP_{0:d}'.format(group_id)] = (4, group_id) 65 | 66 | TRANFORM_ATTRIBUTES = struct.Struct('!2H') # (0b10000000 | 14), Key Length 67 | 68 | AUTH_MAC_SIZE = 32 69 | 70 | 71 | class ProtocolID(IntEnum): 72 | IKE = 1 73 | AH = 2 74 | ESP = 3 75 | 76 | 77 | class MessageType(IntEnum): 78 | Reserved = 0 79 | UNSUPPORTED_CRITICAL_PAYLOAD = 1 80 | INVALID_IKE_SPI = 4 81 | INVALID_MAJOR_VERSION = 5 82 | INVALID_SYNTAX = 7 83 | INVALID_MESSAGE_ID = 9 84 | INVALID_SPI = 11 85 | NO_PROPOSAL_CHOSEN = 14 86 | INVALID_KE_PAYLOAD = 17 87 | AUTHENTICATION_FAILED = 24 88 | SINGLE_PAIR_REQUIRED = 34 89 | NO_ADDITIONAL_SAS = 35 90 | INTERNAL_ADDRESS_FAILURE = 36 91 | FAILED_CP_REQUIRED = 37 92 | TS_UNACCEPTABLE = 38 93 | INVALID_SELECTORS = 39 94 | UNACCEPTABLE_ADDRESSES = 40 95 | UNEXPECTED_NAT_DETECTED = 41 96 | USE_ASSIGNED_HoA = 42 97 | TEMPORARY_FAILURE = 43 98 | CHILD_SA_NOT_FOUND = 44 99 | INVALID_GROUP_ID = 45 100 | AUTHORIZATION_FAILED = 46 101 | INITIAL_CONTACT = 16384 102 | SET_WINDOW_SIZE = 16385 103 | ADDITIONAL_TS_POSSIBLE = 16386 104 | IPCOMP_SUPPORTED = 16387 105 | NAT_DETECTION_SOURCE_IP = 16388 106 | NAT_DETECTION_DESTINATION_IP = 16389 107 | COOKIE = 16390 108 | USE_TRANSPORT_MODE = 16391 109 | HTTP_CERT_LOOKUP_SUPPORTED = 16392 110 | REKEY_SA = 16393 111 | ESP_TFC_PADDING_NOT_SUPPORTED = 16394 112 | NON_FIRST_FRAGMENTS_ALSO = 16395 113 | MOBIKE_SUPPORTED = 16396 114 | ADDITIONAL_IP4_ADDRESS = 16397 115 | ADDITIONAL_IP6_ADDRESS = 16398 116 | NO_ADDITIONAL_ADDRESSES = 16399 117 | UPDATE_SA_ADDRESSES = 16400 118 | COOKIE2 = 16401 119 | NO_NATS_ALLOWED = 16402 120 | AUTH_LIFETIME = 16403 121 | MULTIPLE_AUTH_SUPPORTED = 16404 122 | ANOTHER_AUTH_FOLLOWS = 16405 123 | REDIRECT_SUPPORTED = 16406 124 | REDIRECT = 16407 125 | REDIRECTED_FROM = 16408 126 | TICKET_LT_OPAQUE = 16409 127 | TICKET_REQUEST = 16410 128 | TICKET_ACK = 16411 129 | TICKET_NACK = 16412 130 | TICKET_OPAQUE = 16413 131 | LINK_ID = 16414 132 | USE_WESP_MODE = 16415 133 | ROHC_SUPPORTED = 16416 134 | EAP_ONLY_AUTHENTICATION = 16417 135 | CHILDLESS_IKEV2_SUPPORTED = 16418 136 | QUICK_CRASH_DETECTION = 16419 137 | IKEV2_MESSAGE_ID_SYNC_SUPPORTED = 16420 138 | IPSEC_REPLAY_COUNTER_SYNC_SUPPORTED = 16421 139 | IKEV2_MESSAGE_ID_SYNC = 16422 140 | IPSEC_REPLAY_COUNTER_SYNC = 16423 141 | SECURE_PASSWORD_METHODS = 16424 142 | PSK_PERSIST = 16425 143 | PSK_CONFIRM = 16426 144 | ERX_SUPPORTED = 16427 145 | IFOM_CAPABILITY = 16428 146 | SENDER_REQUEST_ID = 16429 147 | 148 | def __repr__(self): 149 | return u"({0:s}: {1!r:s})".format(self._name_, self._value_) 150 | 151 | 152 | class AuthenticationType(IntEnum): 153 | RSA = 1 154 | PSK = 2 155 | DSS = 3 156 | 157 | AUTH_HEADER = "!B3x" 158 | -------------------------------------------------------------------------------- /ike/initiator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright © 2013-2014 Kimmo Parviainen-Jalanko. 5 | # 6 | 7 | import logging 8 | import asyncio 9 | import os 10 | import docopt 11 | 12 | __doc__ = """ 13 | IKE v2 (RFC 5996) initiator implementation 14 | 15 | Usage: 16 | {} 17 | 18 | To clean up afterwards, :: 19 | 20 | setkey -FP && setkey -F 21 | 22 | """.format(os.path.split(__file__)[-1]) 23 | 24 | 25 | class IKEInitiator(asyncio.DatagramProtocol): 26 | """ 27 | Implements an IKE initiator that attempt to negotiate a single child SA 28 | to remote peer. 29 | """ 30 | def connection_made(self, transport): 31 | from ike.protocol import IKE 32 | self.transport = transport 33 | sock = self.transport.get_extra_info("socket") 34 | address = sock.getsockname() 35 | peer = sock.getpeername() 36 | logger.debug("Socket created from {} to {}".format(address, peer)) 37 | self.ike = IKE(address, peer) 38 | logger.info("Sending INIT") 39 | self.transport.sendto(self.ike.init_send()) # no need for address 40 | 41 | def datagram_received(self, data, address): 42 | from ike.protocol import State 43 | from ike.const import ExchangeType 44 | (host, port) = address 45 | logger.info("Received %r from %s:%d" % (data, host, port)) 46 | packet = self.ike.parse_packet(data=data) 47 | logger.info('{} message {}'.format(packet.exchange_type.name, packet.message_id)) 48 | if self.ike.state == State.INIT and packet.exchange_type == ExchangeType.IKE_SA_INIT: 49 | self.ike.init_recv() 50 | ike_auth = self.ike.auth_send() 51 | logger.info("Sending AUTH") 52 | self.transport.sendto(ike_auth) 53 | logger.info("IKE AUTH SENT") 54 | elif self.ike.state == State.AUTH and packet.exchange_type == ExchangeType.IKE_AUTH: 55 | self.ike.auth_recv() 56 | 57 | # Possibly invoked if there is no server listening on the 58 | # address to which we are sending. 59 | def connectionRefused(self): 60 | logger.info("No one listening") 61 | 62 | 63 | def main(peer): 64 | port = 500 65 | loop = asyncio.get_event_loop() 66 | t = asyncio.Task(loop.create_datagram_endpoint(IKEInitiator, remote_addr=(peer, port))) 67 | # TODO: Retransmissions should be handled here? 68 | loop.run_until_complete(t) 69 | loop.run_forever() 70 | 71 | 72 | if __name__ == '__main__': 73 | opts = docopt.docopt(__doc__) 74 | logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(name)s.%(funcName)s:[%(lineno)s]: %(message)s') 75 | logger = logging.getLogger('MAIN') 76 | logger.info("Starting...") 77 | main(opts['']) 78 | -------------------------------------------------------------------------------- /ike/payloads.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013-2014 Kimmo Parviainen-Jalanko. 4 | # 5 | """ 6 | IKEv2 Payloads as specified in RFC 5996 sections 3.2 - 3.16 7 | """ 8 | from enum import IntEnum 9 | from functools import reduce 10 | import ipaddress 11 | import logging 12 | import operator 13 | import os 14 | import struct 15 | import binascii 16 | 17 | from . import const 18 | from ike.util import pubkey 19 | from ike.util.prf import prf 20 | from .proposal import Proposal 21 | from .util.conv import to_bytes 22 | 23 | 24 | PRIVATE_KEY_PEM = 'tests/private_key.pem' 25 | 26 | __author__ = 'kimvais' 27 | 28 | logger = logging.getLogger(__name__) 29 | 30 | 31 | class Type(IntEnum): 32 | """ 33 | Payload types from `IANA `_ 34 | """ 35 | no_next_payload = 0 36 | SA = 33 37 | KE = 34 38 | IDi = 35 39 | IDr = 36 40 | CERT = 37 41 | CERTREQ = 38 42 | AUTH = 39 43 | Nonce = 40 44 | Ni = 40 45 | Nr = 40 46 | Notify = 41 47 | Delete = 42 48 | Vendor = 43 49 | TSi = 44 50 | TSr = 45 51 | SK = 46 52 | CP = 47 53 | EAP = 48 54 | GSPM = 49 55 | IDg = 50 56 | GSA = 51 57 | KD = 52 58 | Fragment = 132 59 | 60 | def __repr__(self, *args, **kwargs): 61 | return '<{}: {}>'.format(self.name, self.value) 62 | 63 | 64 | class _IkePayload(object): 65 | """ 66 | Generic payload header `RFC5996 Section 3.2 `_ 67 | """ 68 | _type = None 69 | 70 | def __init__(self, data=None, next_payload=Type.no_next_payload, critical=False): 71 | self._type = Type[self.__class__.__name__] 72 | if data is not None: 73 | next_payload, self.flags, self.length = const.PAYLOAD_HEADER.unpack( 74 | data[:const.PAYLOAD_HEADER.size]) 75 | self.next_payload = Type(next_payload) 76 | self.parse(data[const.PAYLOAD_HEADER.size:self.length]) 77 | else: 78 | self.next_payload = next_payload 79 | self.length = 0 80 | self._data = bytearray() 81 | if critical: 82 | self.flags = 0b10000000 83 | else: 84 | self.flags = 0 85 | 86 | @property 87 | def header(self): 88 | return bytearray(const.PAYLOAD_HEADER.pack(self.next_payload, 89 | self.flags, 90 | self.length)) 91 | 92 | def __bytes__(self): 93 | return bytes(self.header + self._data) 94 | 95 | def __unicode__(self): 96 | return "IKE Payload {0!r} [{1}]".format(self._type, 97 | self.length) 98 | 99 | def __repr__(self): 100 | return '<{0}>'.format(self.__unicode__(), hex(id(self))) 101 | 102 | def parse(self, data): 103 | self._data = data 104 | 105 | 106 | class SA(_IkePayload): 107 | """ 108 | `Security Association Payload `_ 109 | """ 110 | def __init__(self, data=None, proposals=None, next_payload=Type.no_next_payload, 111 | critical=False): 112 | super(SA, self).__init__(data, next_payload, critical) 113 | if data is not None: 114 | self.parse(data) 115 | elif proposals is None: 116 | self.proposals = [ 117 | Proposal(None, 1, const.ProtocolID.IKE, transforms=[ 118 | ('ENCR_CAMELLIA_CBC', 256), 119 | ('PRF_HMAC_SHA2_256',), 120 | ('AUTH_HMAC_SHA2_256_128',), 121 | ('DH_GROUP_14',) 122 | ]), 123 | Proposal(None, 2, const.ProtocolID.ESP, transforms=[ 124 | ('ENCR_CAMELLIA_CBC', 256), 125 | ('ESN', ), 126 | ('AUTH_HMAC_SHA2_256_128',) 127 | ]) 128 | ] 129 | self.spi = self.proposals[0].spi 130 | else: 131 | self.proposals = proposals 132 | self.spi = self.proposals[0].spi 133 | 134 | def __bytes__(self): 135 | ret = list() 136 | self.proposals[-1].last = True 137 | ret.extend(proposal.data for proposal in self.proposals) 138 | self.length = 4 + sum((len(x) for x in ret)) 139 | ret.insert(0, self.header) 140 | return bytes(reduce(operator.add, ret)) 141 | 142 | def parse(self, data): 143 | self.proposals = list() 144 | last = False 145 | while not last: 146 | proposal = Proposal(data=data) 147 | if proposal.spi: 148 | logger.debug("Setting SPI to: {}".format(proposal.spi)) 149 | self.spi = proposal.spi 150 | self.proposals.append(proposal) 151 | last = proposal.last 152 | data = data[proposal.len:] 153 | logger.debug("got {} proposals".format(len(self.proposals))) 154 | 155 | 156 | class KE(_IkePayload): 157 | """ 158 | `Key Exchange Payload `_ 159 | """ 160 | def parse(self, data): 161 | self.group, _ = struct.unpack('!2H', data[4:8]) 162 | self.kex_data = data[const.PAYLOAD_HEADER.size + 4:self.length] 163 | logger.debug("group {}".format(self.group)) 164 | logger.debug('KEX data: {}'.format(binascii.hexlify(self.kex_data))) 165 | 166 | def __init__(self, data=None, next_payload=Type.no_next_payload, critical=False, 167 | group=14, diffie_hellman=None): 168 | super(KE, self).__init__(data, next_payload, critical) 169 | if data is not None: 170 | self.parse(data) 171 | else: 172 | self.kex_data = to_bytes(diffie_hellman.public_key) 173 | self._data = struct.pack('!2H', group, 0) + self.kex_data 174 | self.length = const.PAYLOAD_HEADER.size + len(self._data) 175 | 176 | 177 | class Nonce(_IkePayload): 178 | """ 179 | `Nonce Payload `_ 180 | """ 181 | def parse(self, data): 182 | self._data = data[const.PAYLOAD_HEADER.size:self.length] 183 | 184 | def __init__(self, data=None, next_payload=Type.no_next_payload, critical=False, 185 | nonce=None): 186 | super(Nonce, self).__init__(data, next_payload, critical) 187 | if data is not None: 188 | self.parse(data) 189 | else: 190 | if nonce: 191 | self._data = nonce 192 | else: 193 | self._data = os.urandom(32) 194 | self.length = const.PAYLOAD_HEADER.size + len(self._data) 195 | 196 | 197 | class Vendor(_IkePayload): 198 | """ 199 | `Nonce Payload `_ 200 | """ 201 | def parse(self, data): 202 | self._data = data[const.PAYLOAD_HEADER.size:self.length] 203 | 204 | def __init__(self, data=None, next_payload=Type.no_next_payload, critical=False, 205 | vendor=None): 206 | super(Vendor, self).__init__(data, next_payload, critical) 207 | if data is not None: 208 | self.parse(data) 209 | else: 210 | if vendor: 211 | self._data = vendor 212 | else: 213 | self._data = os.urandom(32) 214 | self.length = const.PAYLOAD_HEADER.size + len(self._data) 215 | 216 | 217 | class Notify(_IkePayload): 218 | """ 219 | `Notify Payload `_ 220 | """ 221 | def __init__(self, notify_type=None, data=None, next_payload=Type.no_next_payload, critical=False): 222 | # TODO; Implement generation of notifications with data 223 | assert notify_type or data 224 | super().__init__(data, next_payload, critical) 225 | if notify_type: 226 | self._data = struct.pack('!2BH', 0, 0, notify_type) 227 | self.length = 8 228 | 229 | def parse(self, data): 230 | self._data = data[4:self.length] 231 | self.protocol_id, self.spi_size, message_type = struct.unpack( 232 | '!2BH', data[:4]) 233 | self.spi = data[4:4 + self.spi_size] 234 | self.message_type = const.MessageType(message_type) 235 | if self.message_type < 2 ** 14: 236 | self.level = logging.ERROR 237 | else: 238 | self.level = logging.INFO 239 | logger.log(self.level, self.__unicode__()) 240 | self.notification_data = data[4 + self.spi_size:self.length] 241 | 242 | def __unicode__(self): 243 | if self.protocol_id: 244 | return ''.format( 245 | const.ProtocolID(self.protocol_id), 246 | self.message_type, binascii.hexlify(self.spi), 247 | self.spi_size, self.length) 248 | else: 249 | return ''.format(self.message_type, self.length) 250 | 251 | 252 | class Fragment(_IkePayload): 253 | """ 254 | `Fragment Payload` 255 | """ 256 | def parse(self, data): 257 | self._data = data[const.PAYLOAD_HEADER.size:self.length] 258 | 259 | def __init__(self, data=None, next_payload=Type.no_next_payload, critical=False, 260 | fragment=None): 261 | super(Fragment, self).__init__(data, next_payload, critical) 262 | if data is not None: 263 | self.parse(data) 264 | else: 265 | if fragment: 266 | self._data = fragment 267 | self.length = const.PAYLOAD_HEADER.size + len(self._data) 268 | 269 | 270 | class _TS(_IkePayload): 271 | """ 272 | `Traffic Selector Payload `_ 273 | Single IPv4 address:port 274 | """ 275 | def __init__(self, addr=None, data=None, next_payload=Type.no_next_payload, critical=False): 276 | assert addr or data 277 | super().__init__(data, next_payload, critical) 278 | if addr: 279 | ip = int(ipaddress.IPv4Address(addr[0])) 280 | port = addr[1] 281 | port = 0 282 | 283 | # Generate traffic selector 284 | selector = struct.pack("!2BH2H2I", 7, 0, 16, port, port, ip, ip) 285 | self._data = struct.pack("!B3x", 1) + selector # just a single TS 286 | self.length = len(self._data) + 4 287 | 288 | class TSi(_TS): 289 | """ 290 | `Traffic Selector Payload `_ for initiator 291 | """ 292 | pass 293 | 294 | 295 | class TSr(_TS): 296 | """ 297 | `Traffic Selector Payload `_ for responder 298 | """ 299 | pass 300 | 301 | 302 | class IDi(_IkePayload): 303 | """ 304 | `Identification Payload `_ for initiator 305 | """ 306 | def __init__(self, data=None, next_payload=Type.no_next_payload, critical=False): 307 | super().__init__(data, next_payload, critical) 308 | EMAIL = b'test@77.fi' 309 | self.length = 8 + len(EMAIL) 310 | self._data = struct.pack("!B3x", 3) + EMAIL # ID Type (RFC822 address) + reserved 311 | 312 | 313 | class IDr(_IkePayload): 314 | """ 315 | `Identification Payload `_ for responder 316 | """ 317 | pass 318 | 319 | 320 | class AUTH(_IkePayload): 321 | """ 322 | `Authentication Payload `_ 323 | """ 324 | def __init__(self, signed_octets=None, data=None, next_payload=Type.no_next_payload, critical=False): 325 | assert signed_octets or data 326 | super().__init__(data, next_payload, critical) 327 | if not data: 328 | # Generate auth payload 329 | 330 | # authentication_type = const.AuthenticationType.PSK 331 | authentication_type = const.AuthenticationType.RSA 332 | 333 | if authentication_type == const.AuthenticationType.PSK: 334 | PSK = b"foo" 335 | authentication_data = prf(prf(PSK, b"Key Pad for IKEv2"), signed_octets)[:const.AUTH_MAC_SIZE] 336 | elif authentication_type == const.AuthenticationType.RSA: 337 | # XXX: StrongSwan can not verify SHA-256 signature, so we have to use SHA-1 338 | authentication_data = pubkey.sign(signed_octets, PRIVATE_KEY_PEM, hash_alg='SHA-1') 339 | else: 340 | authentication_data = b'' 341 | raise AssertionError("Unsupported authentication method") 342 | self.length = 8 + len(authentication_data) 343 | self._data = struct.pack(const.AUTH_HEADER, authentication_type) + authentication_data 344 | 345 | 346 | class SK(_IkePayload): 347 | """ 348 | `Encrypted Payload `_ 349 | """ 350 | def __init__(self, data=None, next_payload=Type.no_next_payload, critical=False, iv=None, ciphertext=None): 351 | assert data or (iv and ciphertext) 352 | super().__init__(data, next_payload, critical) 353 | if not data: 354 | self.iv = iv 355 | self.ciphertext = ciphertext 356 | self.length = len(iv) + len(ciphertext) + const.PAYLOAD_HEADER.size + 16 # MACLEN 357 | self._data = self.iv + self.ciphertext + b'\x00' * 16 358 | 359 | def mac(self, hmac): 360 | self._data = self._data[:-16] + hmac 361 | 362 | 363 | # Register payloads in order to be used for get_by_type() 364 | _payload_classes = _IkePayload.__subclasses__() + _TS.__subclasses__() 365 | _payload_map = {x.__name__: x for x in _payload_classes if not x.__name__.startswith('_')} 366 | 367 | 368 | def get_by_type(payload_type): 369 | """ 370 | Returns an IkePayload (sub)class based on the RFC5996 payload_type 371 | :param payload_type: int() Ike Payload type 372 | """ 373 | return _payload_map.get(Type(payload_type).name, _IkePayload) 374 | 375 | -------------------------------------------------------------------------------- /ike/proposal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013-2014 Kimmo Parviainen-Jalanko. 4 | # 5 | """ 6 | Implements Proposal and Transform substructures for Security association (SA) payloads. 7 | 8 | Conforms to `RFC5996 section 3.3 `_ 9 | """ 10 | from functools import reduce 11 | import logging 12 | import os 13 | import operator 14 | import struct 15 | import binascii 16 | 17 | from . import const 18 | from ike.util.conv import to_bytes 19 | 20 | __author__ = 'kimvais' 21 | 22 | logger = logging.getLogger(__name__) 23 | 24 | 25 | class Proposal(object): 26 | def __init__(self, data=None, num=1, protocol=const.ProtocolID.IKE, spi=None, spi_len=0, 27 | last=False, transforms=None): 28 | if data is not None: 29 | self.parse(data) 30 | else: 31 | if transforms == None: 32 | self.transforms = list() 33 | else: 34 | self.transforms = [Transform(*x) for x in transforms] 35 | self.transforms[-1].last = True 36 | self.last = last 37 | self.num = num 38 | self.protocol_id = protocol 39 | if spi is not None: 40 | assert isinstance(spi, int) 41 | spi_str = to_bytes(spi) 42 | self.spi_len = len(spi_str) 43 | else: 44 | self.spi_len = spi_len 45 | if not self.spi_len: 46 | if protocol == const.ProtocolID.IKE: 47 | self.spi_len = 8 48 | elif protocol in (const.ProtocolID.ESP, const.ProtocolID.AH): 49 | self.spi_len = 4 50 | spi = int.from_bytes(os.urandom(self.spi_len), 'big') 51 | self.spi = spi 52 | 53 | @property 54 | def data(self): 55 | self.transforms[-1].last = True 56 | parts = [x.data for x in self.transforms] 57 | self.len = const.PROPOSAL_STRUCT.size + self.spi_len + sum( 58 | len(x) for x in parts) 59 | last = 0 if self.last else 2 60 | parts.insert(0, bytearray(const.PROPOSAL_STRUCT.pack( 61 | last, 62 | 0, 63 | self.len, 64 | self.num, 65 | self.protocol_id, 66 | self.spi_len, 67 | len(self.transforms), 68 | ))) 69 | if self.spi_len == 8: 70 | spi = struct.pack('!Q', self.spi) 71 | else: 72 | spi = struct.pack('!L', self.spi) 73 | parts.insert(1, spi) 74 | return reduce(operator.add, parts) 75 | 76 | def parse(self, data): 77 | last, _, self.len, self.num, self.protocol_id, self.spi_len, transform_count = const.PROPOSAL_STRUCT.unpack( 78 | data[:const.PROPOSAL_STRUCT.size]) 79 | self.last = False if last == 2 else True 80 | logger.debug( 81 | 'Last?:{0}, Len:{1}, Num:{2}, Protocol ID:{3}, SPI len:{4}, Transforms:{5}'.format( 82 | self.last, self.len, self.num, self.protocol_id, self.spi_len, 83 | transform_count)) 84 | if self.spi_len: 85 | self.spi = int(binascii.hexlify( 86 | data[const.PROPOSAL_STRUCT.size:const.PROPOSAL_STRUCT.size + self.spi_len]), 87 | 16) 88 | logger.debug('SPI: {0}'.format(hex(self.spi))) 89 | else: 90 | self.spi = None 91 | 92 | 93 | class Transform(object): 94 | def __init__(self, name, keysize=None, last=False): 95 | super(Transform, self).__init__() 96 | self.attributes = list() 97 | self.last = last 98 | self.transform_type, self.transform_id = const.TRANSFORMS[name] 99 | self.keysize = keysize 100 | if self.transform_type == 1 and self.keysize is not None: 101 | self.attributes.append(const.TRANFORM_ATTRIBUTES.pack( 102 | (0b1000000000000000 | 14), self.keysize)) 103 | self.len = ( 104 | const.TRANSFORM_STRUCT.size + 105 | const.TRANFORM_ATTRIBUTES.size * len(self.attributes)) 106 | 107 | @property 108 | def data(self): 109 | last = 0 if self.last else 3 110 | ret = bytearray( 111 | const.TRANSFORM_STRUCT.pack( 112 | last, 0, self.len, 113 | self.transform_type, 0, self.transform_id)) 114 | for attr in self.attributes: 115 | ret += attr 116 | return ret 117 | -------------------------------------------------------------------------------- /ike/protocol.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2014 Kimmo Parviainen-Jalanko. 4 | # 5 | 6 | """ 7 | High level interface to `IKEv2 protocol `_ 8 | """ 9 | from enum import IntEnum 10 | from functools import reduce 11 | from hmac import HMAC 12 | import logging 13 | import operator 14 | import os 15 | from hashlib import sha256 16 | from struct import unpack 17 | import binascii 18 | import struct 19 | 20 | from . import payloads 21 | from ike.util import pubkey 22 | from ike.util.external import run_setkey 23 | from .util.dump import dump 24 | from .util.cipher import Camellia 25 | from . import const 26 | from . import proposal 27 | from .util.conv import to_bytes 28 | from .util.dh import DiffieHellman 29 | from .util.prf import prf, prfplus 30 | 31 | 32 | SPDADD_SYNTAX = """ 33 | spdadd {myip}[any] {peerip}[any] any -P out ipsec esp/tunnel/{myip}-{peerip}/require; 34 | spdadd {peerip}[any] {myip}[any] any -P in ipsec esp/tunnel/{peerip}-{myip}/require; 35 | """ 36 | ESP_ADD_SYNTAX = 'add {ip_from} {ip_to} esp {spi} -m tunnel -E camellia-cbc 0x{key_e} -A hmac-sha256 0x{key_a}' 37 | 38 | MACLEN = 16 39 | 40 | logger = logging.getLogger(__name__) 41 | 42 | 43 | class State(IntEnum): 44 | STARTING = 0 45 | INIT = 1 46 | AUTH = 2 47 | 48 | 49 | class IkeError(Exception): 50 | pass 51 | 52 | 53 | class IKE(object): 54 | """ 55 | A single IKE negotiation / SA. 56 | 57 | Currently implements only Initiator side of the negotiation. 58 | """ 59 | def __init__(self, address, peer, dh_group=14, nonce_len=32): 60 | """ 61 | 62 | :param address: local address tuple(host, port) 63 | :param peer: remote address tuple(host, port) 64 | :param dh_group: diffie hellman group number 65 | :param nonce_len: length of Nonce data 66 | """ 67 | self.iSPI = 0 # XXX: Should be generated here and passed downwards 68 | self.rSPI = 0 69 | self.diffie_hellman = DiffieHellman(dh_group) 70 | self.Ni = os.urandom(nonce_len) 71 | self.packets = list() 72 | self.state = State.STARTING 73 | self.address = address 74 | self.peer = peer 75 | 76 | def init_send(self): 77 | """ 78 | Generates the first (IKE_INIT) packet for Initiator 79 | 80 | :return: bytes() containing a valid IKE_INIT packet 81 | """ 82 | packet = Packet() 83 | self.packets.append(packet) 84 | packet.add_payload(payloads.SA()) 85 | packet.add_payload(payloads.KE(diffie_hellman=self.diffie_hellman)) 86 | packet.add_payload(payloads.Nonce(nonce=self.Ni)) 87 | packet.iSPI = self.iSPI = packet.payloads[0].spi 88 | self.state = State.INIT 89 | return bytes(packet) 90 | 91 | def auth_send(self): 92 | """ 93 | Generates the second (IKE_AUTH) packet for Initiator 94 | 95 | :return: bytes() containing a valid IKE_INIT packet 96 | """ 97 | assert len(self.packets) == 2 98 | packet = Packet(exchange_type=const.ExchangeType.IKE_AUTH, iSPI=self.iSPI, rSPI=self.rSPI) 99 | 100 | # Add IDi (35) 101 | id_payload = payloads.IDi() 102 | packet.add_payload(id_payload) 103 | 104 | # Add AUTH (39) 105 | signed_octets = bytes(self.packets[0]) + self.Nr + prf(self.SK_pi, id_payload._data) 106 | packet.add_payload(payloads.AUTH(signed_octets)) 107 | 108 | # Add SA (33) 109 | self.esp_SPIout = int.from_bytes(os.urandom(4), 'big') 110 | packet.add_payload(payloads.SA(proposals=[ 111 | proposal.Proposal(protocol=const.ProtocolID.ESP, spi=self.esp_SPIout, last=True, transforms=[ 112 | ('ENCR_CAMELLIA_CBC', 256), ('ESN',), ('AUTH_HMAC_SHA2_256_128',) 113 | ]) 114 | ])) 115 | 116 | # Add TSi (44) 117 | packet.add_payload(payloads.TSi(addr=self.address)) 118 | 119 | # Add TSr (45) 120 | packet.add_payload(payloads.TSr(addr=self.peer)) 121 | 122 | # Add N(INITIAL_CONTACT) 123 | packet.add_payload(payloads.Notify(notify_type=const.MessageType.INITIAL_CONTACT)) 124 | 125 | self.packets.append(packet) 126 | self.state = State.AUTH 127 | 128 | return self.encrypt_and_hmac(packet) 129 | 130 | def init_recv(self): 131 | """ 132 | Parses the IKE_INIT response packet received from Responder. 133 | 134 | Assigns the correct values of rSPI and Nr 135 | Calculates Diffie-Hellman exchange and assigns all keys to self. 136 | 137 | """ 138 | assert len(self.packets) == 2 139 | packet = self.packets[-1] 140 | for p in packet.payloads: 141 | if p._type == payloads.Type.Nr: 142 | self.Nr = p._data 143 | logger.debug(u"Responder nonce {}".format(binascii.hexlify(self.Nr))) 144 | elif p._type == payloads.Type.KE: 145 | int_from_bytes = int.from_bytes(p.kex_data, 'big') 146 | self.diffie_hellman.derivate(int_from_bytes) 147 | else: 148 | logger.debug('Ignoring: {}'.format(p)) 149 | 150 | logger.debug('Nonce I: {}\nNonce R: {}'.format(binascii.hexlify(self.Ni), binascii.hexlify(self.Nr))) 151 | logger.debug('DH shared secret: {}'.format(binascii.hexlify(self.diffie_hellman.shared_secret))) 152 | 153 | SKEYSEED = prf(self.Ni + self.Nr, self.diffie_hellman.shared_secret) 154 | 155 | logger.debug(u"SKEYSEED is: {0!r:s}\n".format(binascii.hexlify(SKEYSEED))) 156 | 157 | keymat = prfplus(SKEYSEED, (self.Ni + self.Nr + 158 | to_bytes(self.iSPI) + to_bytes(self.rSPI)), 159 | 32 * 7) 160 | #3 * 32 + 2 * 32 + 2 * 32) 161 | 162 | logger.debug("Got %d bytes of key material" % len(keymat)) 163 | # get keys from material 164 | ( self.SK_d, 165 | self.SK_ai, 166 | self.SK_ar, 167 | self.SK_ei, 168 | self.SK_er, 169 | self.SK_pi, 170 | self.SK_pr ) = unpack("32s" * 7, keymat) # XXX: Should support other than 256-bit algorithms, really. 171 | 172 | logger.debug("SK_ai: {}".format(dump(self.SK_ai))) 173 | logger.debug("SK_ei: {}".format(dump(self.SK_ei))) 174 | 175 | def authenticate_peer(self, auth_data, peer_id, message): 176 | """ 177 | Verifies the peers authentication. 178 | """ 179 | logger.debug('message: {}'.format(dump(message))) 180 | signed_octets = message + self.Ni + prf(self.SK_pr, peer_id._data) 181 | auth_type = const.AuthenticationType(struct.unpack(const.AUTH_HEADER, auth_data[:4])[0]) 182 | assert auth_type == const.AuthenticationType.RSA 183 | logger.debug(dump(auth_data)) 184 | try: 185 | return pubkey.verify(signed_octets, auth_data[4:], 'tests/peer.pem') 186 | except pubkey.VerifyError: 187 | raise IkeError("Remote peer authentication failed.") 188 | 189 | def install_ipsec_sas(self): 190 | logger.debug("ESP Ai: {}".format(dump(self.esp_ai))) 191 | logger.debug("ESP Ar: {}".format(dump(self.esp_ar))) 192 | logger.debug("ESP Ei: {}".format(dump(self.esp_ei))) 193 | logger.debug("ESP Er: {}".format(dump(self.esp_er))) 194 | outbound_params = dict(spi=self.esp_SPIout, 195 | key_e=binascii.hexlify(self.esp_ei).decode('ascii'), 196 | key_a=binascii.hexlify(self.esp_ai).decode('ascii'), 197 | ip_from=self.address[0], 198 | ip_to=self.peer[0]) 199 | inbound_params = dict(spi=self.esp_SPIin, 200 | key_e=binascii.hexlify(self.esp_er).decode('ascii'), 201 | key_a=binascii.hexlify(self.esp_ar).decode('ascii'), 202 | ip_to=self.address[0], 203 | ip_from=self.peer[0]) 204 | setkey_input = "flush;\nspdflush;\n{0};\n{1};\n{2}\ndump esp;".format( 205 | ESP_ADD_SYNTAX.format( **outbound_params), 206 | ESP_ADD_SYNTAX.format( **inbound_params), 207 | SPDADD_SYNTAX.format(myip=self.address[0], peerip=self.peer[0])) 208 | cmd_output = run_setkey(setkey_input) 209 | logger.info('Ipsec SAs installed:') 210 | for line in cmd_output.splitlines(): 211 | logger.info('... {}'.format(line)) 212 | 213 | def auth_recv(self): 214 | """ 215 | Handle peer's IKE_AUTH response. 216 | """ 217 | id_r = auth_data = None 218 | for p in self.packets[-1].payloads: 219 | if p._type == payloads.Type.IDr: 220 | id_r = p 221 | logger.debug('Got responder ID: {}'.format(dump(bytes(p)))) 222 | if p._type == payloads.Type.AUTH: 223 | auth_data = p._data 224 | if p._type == payloads.Type.SA: 225 | logger.debug('ESP_SPIin: {}'.format(p.spi)) 226 | self.esp_SPIin = p.spi 227 | for proposal in p.proposals: 228 | logger.debug("Proposal: {}".format(proposal.__dict__)) 229 | logger.debug(proposal.spi) 230 | if id_r is None or auth_data is None: 231 | raise IkeError('IDr missing from IKE_AUTH response') 232 | message2 = bytes(self.packets[1]) 233 | authenticated = self.authenticate_peer(auth_data, id_r, message2) 234 | assert authenticated 235 | keymat = prfplus(self.SK_d, self.Ni + self.Nr, 4 * 32) 236 | (self.esp_ei, 237 | self.esp_ai, 238 | self.esp_er, 239 | self.esp_ar, 240 | ) = unpack("32s" * 4, keymat) 241 | # TODO: Figure out the names for the params, they _ARE_ in correct places, just the names migth mismatch. 242 | self.install_ipsec_sas() 243 | 244 | def encrypt_and_hmac(self, packet): 245 | """ 246 | Encrypts and signs a Packet() using self.SK_ei and self.SK_ai 247 | 248 | :param packet: Unecrypted Packet() with one or more payloads. 249 | :return: Encrypted and signed Packet() with a single payloads.SK 250 | """ 251 | final = Packet(exchange_type=packet.exchange_type, iSPI=packet.iSPI, rSPI=packet.rSPI, message_id=1) 252 | # Set up crypto 253 | iv = os.urandom(16) 254 | ikecrypto = Camellia(self.SK_ei, iv) 255 | ikehash = HMAC(self.SK_ai, digestmod=sha256) 256 | logger.debug('IV: {}'.format(dump(iv))) 257 | 258 | # Encrypt 259 | plain = bytes(packet)[const.IKE_HEADER.size:] 260 | ciphertext = ikecrypto.encrypt(plain) 261 | sk = payloads.SK(next_payload=packet.payloads[0]._type, iv=iv, ciphertext=ciphertext) 262 | final.add_payload(sk) 263 | logger.debug(dump(bytes(final))) 264 | 265 | # Sign 266 | ikehash.update(bytes(final)[:-MACLEN]) 267 | mac = ikehash.digest()[:MACLEN] 268 | sk.mac(mac) 269 | 270 | logger.debug(dump(bytes(final))) 271 | return bytes(final) 272 | 273 | def decrypt(self, data): 274 | """ 275 | Decrypts an encrypted (SK, 46) IKE payload using self.SK_er 276 | 277 | :param data: Encrypted IKE payload including headers (payloads.SK()) 278 | :return: next_payload, data_containing_payloads 279 | :raise IkeError: If packet is corrupted. 280 | """ 281 | next_payload, is_critical, payload_len = const.PAYLOAD_HEADER.unpack(data[:const.PAYLOAD_HEADER.size]) 282 | next_payload = payloads.Type(next_payload) 283 | logger.debug("next payload: {!r}".format(next_payload)) 284 | try: 285 | iv_len = 16 286 | iv = bytes(data[const.PAYLOAD_HEADER.size:const.PAYLOAD_HEADER.size + iv_len]) 287 | ciphertext = bytes(data[const.PAYLOAD_HEADER.size + iv_len:payload_len]) # HMAC size 288 | except IndexError: 289 | raise IkeError('Unable to decrypt: Malformed packet') 290 | logger.debug('IV: {}'.format(dump(iv))) 291 | logger.debug('CIPHERTEXT: {}'.format(dump(ciphertext))) 292 | # Decrypt 293 | cipher = Camellia(self.SK_er, iv=iv) 294 | decrypted = cipher.decrypt(ciphertext) 295 | logger.debug("Decrypted packet from responder: {}".format(dump(decrypted))) 296 | return next_payload, decrypted 297 | 298 | def verify_hmac(self, data): 299 | """ 300 | Verifies the HMAC signature of an encrypted (SK, 46) payload using self.SK_ar 301 | 302 | :param data: bytes(payloads.SK()) 303 | :raise IkeError: if calculated signature does not match the one in the payload 304 | """ 305 | hmac = HMAC(self.SK_ar, digestmod=sha256) 306 | hmac_theirs = data[-MACLEN:] 307 | hmac.update(data[:-MACLEN]) 308 | hmac_ours = hmac.digest()[:MACLEN] 309 | logger.debug('HMAC verify (ours){} (theirs){}'.format( 310 | binascii.hexlify(hmac_ours), binascii.hexlify(hmac_theirs))) 311 | if hmac_ours != hmac_theirs: 312 | raise IkeError('HMAC verify failed') 313 | 314 | def parse_packet(self, data): 315 | """ 316 | Parses a received packet in to Packet() with corresponding payloads. 317 | Will decrypt encrypted packets when needed. 318 | 319 | :param data: bytes() IKE packet from wire. 320 | :return: Packet() instance 321 | :raise IkeError: on malformed packet 322 | """ 323 | packet = Packet(data=data) 324 | packet.header = data[0:const.IKE_HEADER.size] 325 | (packet.iSPI, packet.rSPI, next_payload, packet.version, exchange_type, packet.flags, 326 | packet.message_id, packet.length) = const.IKE_HEADER.unpack(packet.header) 327 | packet.exchange_type = const.ExchangeType(exchange_type) 328 | if self.iSPI != packet.iSPI: 329 | raise IkeError("Initiator SPI mismatch, packet to an unknown IKE SA") 330 | elif not self.rSPI: 331 | logger.debug("Setting responder SPI: {0:x}".format(packet.rSPI)) 332 | self.rSPI = packet.rSPI 333 | elif self.rSPI != packet.rSPI: 334 | raise IkeError("Responder SPI mismatch, packet to an unknown IKE SA") 335 | if packet.message_id - int(self.state) != 1: 336 | logger.debug("message ID {} at state {!r}".format(packet.message_id, self.state)) 337 | logger.debug("next payload: {!r}".format(next_payload)) 338 | if next_payload == 46: 339 | self.verify_hmac(data) 340 | next_payload, data = self.decrypt(data[const.IKE_HEADER.size:]) 341 | else: 342 | data = data[const.IKE_HEADER.size:] 343 | while next_payload: 344 | logger.debug('Next payload: {0!r}'.format(next_payload)) 345 | logger.debug('{0} bytes remaining'.format(len(data))) 346 | try: 347 | payload = payloads.get_by_type(next_payload)(data=data) 348 | except KeyError as e: 349 | logger.error("Unidentified payload {}".format(e)) 350 | payload = payloads._IkePayload(data=data) 351 | packet.payloads.append(payload) 352 | logger.debug('Payloads: {0!r}'.format(packet.payloads)) 353 | next_payload = payload.next_payload 354 | data = data[payload.length:] 355 | logger.debug("Packed parsed successfully") 356 | self.packets.append(packet) 357 | return packet 358 | 359 | 360 | class Packet(object): 361 | """ 362 | An IKE packet. 363 | 364 | To generate packets: 365 | 366 | #. instantiate an Packet() 367 | #. add payloads by Packet.add_payload() 368 | #. send bytes(Packet) to other peer. 369 | 370 | Received packets should be generated by IKE.parse_packet(). 371 | """ 372 | def __init__(self, data=None, exchange_type=None, message_id=0, iSPI=0, rSPI=0): 373 | self.raw_data = data 374 | if exchange_type is None: 375 | exchange_type=const.ExchangeType.IKE_SA_INIT 376 | self.payloads = list() 377 | self.iSPI = iSPI 378 | self.rSPI = rSPI 379 | self.message_id = message_id 380 | self.exchange_type = exchange_type 381 | 382 | def add_payload(self, payload): 383 | """ 384 | Adds a payload to packet, updating last payload's next_payload field 385 | """ 386 | if self.payloads: 387 | self.payloads[-1].next_payload = payload._type 388 | self.payloads.append(payload) 389 | 390 | def __bytes__(self): 391 | if self.raw_data is not None: 392 | return self.raw_data 393 | data = reduce(operator.add, (bytes(x) for x in self.payloads)) 394 | length = len(data) + const.IKE_HEADER.size 395 | header = bytearray(const.IKE_HEADER.pack( 396 | self.iSPI, 397 | self.rSPI, 398 | self.payloads[0]._type, 399 | const.IKE_VERSION, 400 | self.exchange_type, 401 | const.IKE_HDR_FLAGS['I'], 402 | self.message_id, 403 | length 404 | )) 405 | return bytes(header + data) 406 | 407 | 408 | 409 | 410 | 411 | -------------------------------------------------------------------------------- /ike/util/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013 Kimmo Parviainen-Jalanko. 4 | # 5 | __author__ = 'kimvais' 6 | -------------------------------------------------------------------------------- /ike/util/cipher.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright © 2014 Kimmo Parviainen-Jalanko 5 | # 6 | import locale 7 | import os 8 | import sys 9 | 10 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 11 | from cryptography.hazmat.backends.openssl import backend 12 | 13 | 14 | def pad(data, blocksize=16): 15 | """ 16 | Pads data to blocksize according to RFC 4303. Pad length field is included in output. 17 | """ 18 | padlen = blocksize - len(data) % blocksize 19 | return bytes(data + bytearray(range(1, padlen)) + bytearray((padlen - 1,))) 20 | 21 | 22 | class _Cipher(object): 23 | algorithm = None 24 | 25 | def __init__(self, key, iv=None): 26 | if iv is None: 27 | self.iv = os.urandom(16) 28 | else: 29 | assert len(iv) == 16 30 | self.iv = iv 31 | self.cipher = Cipher(self.algorithm(key), modes.CBC(self.iv), backend=backend) 32 | self.enc = self.cipher.encryptor() 33 | self.dec = self.cipher.decryptor() 34 | 35 | def encrypt(self, data): 36 | return self.enc.update(pad(data)) + self.enc.finalize() 37 | 38 | def decrypt(self, data): 39 | plain = self.dec.update(data) + self.dec.finalize() 40 | return plain 41 | padlen = plain[-1] 42 | return plain[:-padlen] 43 | 44 | 45 | class Camellia(_Cipher): 46 | algorithm = algorithms.Camellia 47 | 48 | 49 | class AES(_Cipher): 50 | algorithm = algorithms.AES 51 | 52 | 53 | if __name__ == '__main__': 54 | c = Camellia(16 * b'k') 55 | ciphertext = c.encrypt(' '.join(sys.argv[1:]).encode(locale.getpreferredencoding())) 56 | print(ciphertext) 57 | print(c.decrypt(ciphertext)) 58 | -------------------------------------------------------------------------------- /ike/util/conv.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | __author__ = 'kimvais' 4 | 5 | 6 | def to_bytes(x): 7 | # Converts an integer of arbitrary length to network-endian bytes 8 | l = math.ceil(x.bit_length() / 8) 9 | return x.to_bytes(l, 'big') -------------------------------------------------------------------------------- /ike/util/dh.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013 Kimmo Parviainen-Jalanko. 4 | # 5 | import os 6 | import re 7 | import logging 8 | import binascii 9 | from .conv import to_bytes 10 | 11 | logging.basicConfig() 12 | logger = logging.getLogger(__name__) 13 | logger.setLevel(logging.CRITICAL) 14 | 15 | _PRIME_STRS = { 16 | 1: ''' FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 17 | 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD 18 | EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 19 | E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF''', 20 | 2: '''FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 21 | 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD 22 | EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 23 | E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED 24 | EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 25 | FFFFFFFF FFFFFFFF''', 26 | 5: '''FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 27 | 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD 28 | EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 29 | E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED 30 | EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D 31 | C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F 32 | 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D 33 | 670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF''', 34 | 14: '''FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 35 | 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD 36 | EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 37 | E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED 38 | EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D 39 | C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F 40 | 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D 41 | 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B 42 | E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 43 | DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 44 | 15728E5A 8AACAA68 FFFFFFFF FFFFFFFF''', 45 | 15: '''FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 46 | 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD 47 | EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 48 | E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED 49 | EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D 50 | C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F 51 | 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D 52 | 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B 53 | E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 54 | DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 55 | 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 56 | ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 57 | ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B 58 | F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C 59 | BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 60 | 43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF''', 61 | 16: '''FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 62 | 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD 63 | EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 64 | E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED 65 | EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D 66 | C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F 67 | 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D 68 | 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B 69 | E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 70 | DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 71 | 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 72 | ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 73 | ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B 74 | F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C 75 | BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 76 | 43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 77 | 88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA 78 | 2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6 79 | 287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED 80 | 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9 81 | 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199 82 | FFFFFFFF FFFFFFFF''', 83 | 17: '''FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 84 | 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 85 | 302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 86 | A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 87 | 49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 88 | FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D 89 | 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C 90 | 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718 91 | 3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D 92 | 04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D 93 | B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 94 | 1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C 95 | BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC 96 | E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26 97 | 99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB 98 | 04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2 99 | 233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 100 | D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492 101 | 36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406 102 | AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918 103 | DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151 104 | 2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03 105 | F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F 106 | BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA 107 | CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B 108 | B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632 109 | 387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E 110 | 6DCC4024 FFFFFFFF FFFFFFFF''', 111 | 18: '''FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 112 | 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD 113 | EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 114 | E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED 115 | EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D 116 | C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F 117 | 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D 118 | 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B 119 | E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 120 | DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 121 | 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 122 | ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 123 | ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B 124 | F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C 125 | BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 126 | 43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 127 | 88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA 128 | 2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6 129 | 287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED 130 | 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9 131 | 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492 132 | 36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD 133 | F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831 134 | 179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B 135 | DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF 136 | 5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6 137 | D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3 138 | 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA 139 | CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 140 | 06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C 141 | DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE 142 | 12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4 143 | 38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300 144 | 741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568 145 | 3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9 146 | 22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B 147 | 4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A 148 | 062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36 149 | 4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1 150 | B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92 151 | 4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47 152 | 9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71 153 | 60C980DD 98EDD3DF FFFFFFFF FFFFFFFF''' 154 | } 155 | 156 | PRIMES = dict( 157 | (k, int(re.sub('\s+', '', v), 16)) for k, v in _PRIME_STRS.items()) 158 | 159 | 160 | class DiffieHellman(object): 161 | generator = 2 162 | 163 | def __init__(self, group=14, n=64): 164 | self.group = group 165 | self.bits = n * 8 166 | self.generate_private_key(n) 167 | self.generate_public_key() 168 | 169 | def generate_private_key(self, n): 170 | self.private_key = int(binascii.hexlify(os.urandom(n)), 16) 171 | 172 | def generate_public_key(self): 173 | self.public_key = pow(self.generator, self.private_key, 174 | PRIMES[self.group]) 175 | 176 | def derivate(self, other_key): 177 | self._s = pow(other_key, self.private_key, PRIMES[self.group]) 178 | return self.shared_secret 179 | 180 | @property 181 | def shared_secret(self): 182 | return to_bytes(self._s) 183 | -------------------------------------------------------------------------------- /ike/util/dump.py: -------------------------------------------------------------------------------- 1 | import binascii 2 | 3 | def dump(src): 4 | """ 5 | Returns data in hex format in groups of 4 octets delimited by spaces for debugging purposes. 6 | """ 7 | return b' '.join(binascii.hexlify(bytes(x)) for x in zip(src[::4], src[1::4], src[2::4], src[3::4])) 8 | -------------------------------------------------------------------------------- /ike/util/external.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2013-2014 Kimmo Parviainen-Jalanko. 4 | # 5 | 6 | import os 7 | import subprocess 8 | import tempfile 9 | 10 | __author__ = 'kimvais' 11 | 12 | 13 | def run_setkey(input): 14 | """ 15 | Runs a script through the 'setkey' command that is a user space insterface for PFKEY. 16 | :param input: setkey configuration file contents. 17 | """ 18 | SETKEY_BINARY = '/usr/sbin/setkey' 19 | fd, filename = tempfile.mkstemp('w') 20 | f = os.fdopen(fd, 'w') 21 | f.write(input) 22 | f.close() 23 | output = subprocess.check_output(['sudo', SETKEY_BINARY, '-f', filename]) 24 | os.remove(filename) 25 | return output.decode('utf-8') -------------------------------------------------------------------------------- /ike/util/prf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2014 Kimmo Parviainen-Jalanko. 4 | # 5 | from hmac import HMAC 6 | import hashlib 7 | from struct import pack 8 | 9 | 10 | def prf(key, data, hash_algorithm='sha256'): 11 | hasher = getattr(hashlib, hash_algorithm) 12 | m = HMAC(key, digestmod=hasher) 13 | m.update(data) 14 | return m.digest() 15 | 16 | 17 | def prfplus(key, data, n): 18 | ret = bytes() 19 | prev = bytes() 20 | round = 1 21 | while len(ret) < n: 22 | prev = prf(key, prev + data + pack("!B", round)) 23 | ret += prev 24 | round += 1 25 | return ret[:n] -------------------------------------------------------------------------------- /ike/util/pubkey.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright © 2014 Kimmo Parviainen-Jalanko 5 | 6 | import rsa 7 | 8 | VerifyError = rsa.VerificationError 9 | 10 | 11 | def sign(data, filename, hash_alg="SHA-256"): 12 | assert isinstance(data, bytes) 13 | with open(filename, 'rb') as keyfile: 14 | private_key = rsa.PrivateKey.load_pkcs1(keyfile.read()) 15 | return rsa.sign(data, private_key, hash_alg) 16 | 17 | 18 | def verify(data, signature, filename): 19 | with open(filename, 'rb') as publicfile: 20 | public_key = rsa.PublicKey.load_pkcs1(publicfile.read()) 21 | try: 22 | return rsa.verify(data, signature, public_key) 23 | except rsa.VerificationError: 24 | raise 25 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from setuptools import setup 4 | from ike import __version__ 5 | 6 | def readme(): 7 | with open('docs/readme.rst') as f: 8 | return f.read() 9 | 10 | 11 | setup(name='ike', 12 | version='.'.join('{}'.format(x) for x in __version__), 13 | description='Minimalistic Internet Key Exchange protocol v2 (RFC 5996) library', 14 | long_description=readme(), 15 | author='Kimmo Parviainen-Jalanko', 16 | author_email='k@77.fi', 17 | url='http://github.com/kimvais/ike/', 18 | download_url='https://github.com/kimvais/ike/releases', 19 | packages=['ike', 'ike.util'], 20 | install_requires=[ 21 | 'rsa', 22 | 'cryptography' 23 | ], 24 | classifiers=[ 25 | 'Development Status :: 3 - Alpha', 26 | 'License :: OSI Approved :: MIT License', 27 | 'Operating System :: Unix', 28 | 'Programming Language :: Python :: 3.4', 29 | 'Topic :: Communications', 30 | 'Topic :: Internet', 31 | 'Topic :: Security', 32 | 'Topic :: Security :: Cryptography', 33 | ] 34 | ) 35 | -------------------------------------------------------------------------------- /tests/ipsec.conf: -------------------------------------------------------------------------------- 1 | config setup 2 | # strictcrlpolicy=yes 3 | # uniqueids = no 4 | charondebug="4" 5 | 6 | conn %default 7 | left=%defaultroute 8 | leftsigkey=/etc/ipsec.d/my.pem 9 | leftauth=rsa-2048-sha256-sha384-sha512 10 | leftid="gw@ipsec.com" 11 | authby=rsasig 12 | auto=add 13 | 14 | conn pyike 15 | right=%any 16 | rightid=test@77.fi 17 | rightsigkey=/etc/ipsec.d/strongswan.pem 18 | rightauth=rsa-2048-sha256-sha384-sha512 19 | authby=rsasig 20 | #authby=psk 21 | -------------------------------------------------------------------------------- /tests/ipsec.secrets: -------------------------------------------------------------------------------- 1 | #: PSK "foo" 2 | : RSA /etc/ipsec.d/private/rpi.pem "Finnair12" 3 | -------------------------------------------------------------------------------- /tests/peer.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0iPN+gfx2Z4kpTEjzlCy 3 | B1BglxbFeiX9NNZWtHytuiJd7ZCcsSopVgiLUvT4m3QoZwwd0FKwjnu+p0rn7jEy 4 | qRid9cZ6qCER/Ksgy77p/OCU8lZh6aniKLM+D6MJ2MPQjxDVhkJbHWURc7Eo9Ga/ 5 | sxs/Ow9KuCb+LDn/YICUEZ+bFCdeGyHPv8573Mksi03o6P/niY4UaRO3hmczPoyy 6 | Sz8KZlrEpubO9/NFE3P0SW86yJFUQ4KA4riw88hl2d/2cAscH4OpSXESFe0Osl4L 7 | ZeyJYElFKUzWKlCzpP4ctusI3um6T8oqfkGirWPIACuFgt3oxcQxPMrK26qhjWgJ 8 | fQIDAQAB 9 | -----END PUBLIC KEY----- 10 | 11 | -----BEGIN RSA PUBLIC KEY----- 12 | MIIBCgKCAQEA0iPN+gfx2Z4kpTEjzlCyB1BglxbFeiX9NNZWtHytuiJd7ZCcsSop 13 | VgiLUvT4m3QoZwwd0FKwjnu+p0rn7jEyqRid9cZ6qCER/Ksgy77p/OCU8lZh6ani 14 | KLM+D6MJ2MPQjxDVhkJbHWURc7Eo9Ga/sxs/Ow9KuCb+LDn/YICUEZ+bFCdeGyHP 15 | v8573Mksi03o6P/niY4UaRO3hmczPoyySz8KZlrEpubO9/NFE3P0SW86yJFUQ4KA 16 | 4riw88hl2d/2cAscH4OpSXESFe0Osl4LZeyJYElFKUzWKlCzpP4ctusI3um6T8oq 17 | fkGirWPIACuFgt3oxcQxPMrK26qhjWgJfQIDAQAB 18 | -----END RSA PUBLIC KEY----- 19 | -------------------------------------------------------------------------------- /tests/private_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA7wkdT/Ohvx41iZY/AgesrxNgTS91JUWuaa3bDZvaeNQzThU/ 3 | lhgn7AbBEO1jDFNTr/Yp7co9s2Pxo0n5U9VQ+2lsvJsdqiUyHOScPZ47JvPTEsWy 4 | RB+lyb5XO1hirDZDtFjGZS77lkEuBxs+KQosFbOj0WENEty5PxfxB1beAgYow4dr 5 | UwnTX6qDTsJbYOQg1hhYnFiJQ5iPWREuQloiks92lHaR/hWDdZcNwPA4zhIZqK/1 6 | j6OIe1G8QtZibyE1aFPhouCM7U+dpNue2/gQFyIn5+A7EPrsZKtbz6JLIX5jkJnI 7 | RRgHmg9geJzzH75GtB2EJmZLiPaCHhjaUV/FcQIDAQABAoIBAQCyt0bSKx6IjOaM 8 | Sugq9V/3ue3rZ4sXZeTEIHdB0n/ijQ0a2SokZ0UZ4+bfaA0A/x/31H1+yxGcmSHl 9 | 6v3d3wRgJG9nCDaCqrKwBYCHVVF2iyAJzgO9iUfj8Uq5FRkZFq1CHomexyTVL0Bh 10 | kc3E01UomJnnhr9Glf5unNDZounz6gMGKCzWVEb8ZRNzQNVAgSYfU/7RJGUWb3hb 11 | Muld2Qr8WaMoL9/FCLMXTuRwMf0kW8TABadQCyU2kBh2Hipy57ePECqCrhcjIm7t 12 | rapAGJdeyIEewbnQgBLopOXKXzAjICEC6/vHOclRmPtAf2oGu9cT2vnZDTNIQSh6 13 | rRnN924RAoGBAPt44Q0JbRAT7oEstpHEX/XkN8FSpO50OJEPeCyO5kNRhaB9UHHW 14 | ZLZFnAImA3RQdT2BpDrmD/4l2MGuM3ByHdT902M25Xw3Yt5GNeAt5/bPC6WwOGMD 15 | 4jbqTMJGVKqrvD324ugSJyHeaT8ryXTC/f7Zbj85IRrp0EE6ialjsvgNAoGBAPNW 16 | 6TTj85loH+HtRrE19JJY+UFqbBApHW2FWEKvjuOsSO9c2vb8VvbDxNYUJ3gm+/Jy 17 | bJdnN2Hi9qaxgRzweoAOrQUjid7AexCx+K+I+sJSSs6wPs+XYw7YoKLpv9ghtCTt 18 | HAEvnX6Lk2vs/Oao/+LKjlhrbv7S3DTnkEZ8GKX1AoGANWDALHs+ujXw31x1WFWd 19 | pN0PdKqtNaxXwXrOIG8os0tfmORgqfk/IW1/IvmcrBjT+f1FtfbVmDXCX8IxSwH+ 20 | ERLbxuiFJ6u+Ab5Xe0FjRoFGUKIqJeJSJyPurSIuoJeZenGoUmhgBBFot678sRse 21 | vPS8MRFYVJUizmW1iM4P1BUCgYA+sqgH3qwHXNLKLY7HXjWT96TRfBA34cAZVgA1 22 | vnI8q0lnky8/8CigEDUJS8wXo0PLZjwgjpGwgQA4VwgDYtrNX/qolk2RvVp4JMME 23 | x3CE3Rs1QigM6N63Fo3dLAkoMRbvZMCQdapIzsG/TyKic+zqjHI8ygGhWscuQnPk 24 | FVlseQKBgA64PiNw8jo9I14EJgbc/ZIkttXRDYyQAJ1sX3+3ZMJKi7htpU2xRwrs 25 | DeS8wBlg3NhHvLkol7OJrJ3PFV9skafhnsXeV+VlDHeH3Mk9ChNV4Hl2RAZMS2gb 26 | UJZF1a/9vZdyAEghFfbn/weW6j7A9pYnfMSsjcJTfhdk391x4+SX 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /tests/public_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PUBLIC KEY----- 2 | MIIBCgKCAQEA7wkdT/Ohvx41iZY/AgesrxNgTS91JUWuaa3bDZvaeNQzThU/lhgn 3 | 7AbBEO1jDFNTr/Yp7co9s2Pxo0n5U9VQ+2lsvJsdqiUyHOScPZ47JvPTEsWyRB+l 4 | yb5XO1hirDZDtFjGZS77lkEuBxs+KQosFbOj0WENEty5PxfxB1beAgYow4drUwnT 5 | X6qDTsJbYOQg1hhYnFiJQ5iPWREuQloiks92lHaR/hWDdZcNwPA4zhIZqK/1j6OI 6 | e1G8QtZibyE1aFPhouCM7U+dpNue2/gQFyIn5+A7EPrsZKtbz6JLIX5jkJnIRRgH 7 | mg9geJzzH75GtB2EJmZLiPaCHhjaUV/FcQIDAQAB 8 | -----END RSA PUBLIC KEY----- 9 | -------------------------------------------------------------------------------- /tests/strongswan.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7wkdT/Ohvx41iZY/Ages 3 | rxNgTS91JUWuaa3bDZvaeNQzThU/lhgn7AbBEO1jDFNTr/Yp7co9s2Pxo0n5U9VQ 4 | +2lsvJsdqiUyHOScPZ47JvPTEsWyRB+lyb5XO1hirDZDtFjGZS77lkEuBxs+KQos 5 | FbOj0WENEty5PxfxB1beAgYow4drUwnTX6qDTsJbYOQg1hhYnFiJQ5iPWREuQloi 6 | ks92lHaR/hWDdZcNwPA4zhIZqK/1j6OIe1G8QtZibyE1aFPhouCM7U+dpNue2/gQ 7 | FyIn5+A7EPrsZKtbz6JLIX5jkJnIRRgHmg9geJzzH75GtB2EJmZLiPaCHhjaUV/F 8 | cQIDAQAB 9 | -----END PUBLIC KEY----- 10 | --------------------------------------------------------------------------------