diff --git a/docs/user/app/Key.dox b/docs/user/app/Key.dox index 46a7ea56fa..ce7681ebc1 100644 --- a/docs/user/app/Key.dox +++ b/docs/user/app/Key.dox @@ -1,5 +1,5 @@ /* - * Copyright 2019 Haiku, Inc. All rights reserved. + * Copyright 2020 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -16,7 +16,11 @@ \ingroup app \ingroup libbe \brief Provides BKey and BPasswordKey classes, as well as BKeyPurpose and - BKeyType enums. + BKeyType enums. + + See the \link app_keystore overview to the Password and Key Storage API + \endlink for an introduction to the API. + */ @@ -24,58 +28,79 @@ /*! - \enum BKeyPurpose - \brief Undocumented + \enum BKeyPurpose + \brief Descriptive constant for the purpose of the key - \since Haiku R1 + \since Haiku R1 */ /*! - \var BKeyPurpose::B_KEY_PURPOSE_ANY - \brief Undocumented + \var BKeyPurpose::B_KEY_PURPOSE_ANY + \brief Query the key store for keys with any purpose. - \since Haiku R1 + This constant does not represent a key purpose by itself, but rather is + used in querying the key store where you do not know or care about the + purpose of key you are looking for. + + \since Haiku R1 */ /*! - \var BKeyPurpose::B_KEY_PURPOSE_GENERIC - \brief Undocumented + \var BKeyPurpose::B_KEY_PURPOSE_GENERIC + \brief Generic key purpose - \since Haiku R1 + This type identifies keys that are not for a specific purpose. + + \since Haiku R1 */ /*! - \var BKeyPurpose::B_KEY_PURPOSE_KEYRING - \brief Undocumented + \var BKeyPurpose::B_KEY_PURPOSE_KEYRING + \brief Keyring key purpose - \since Haiku R1 + This is a key purpose that is internal to the \c keystore_server. It + represents the internals of a keyring. You cannot directly access and + manipulate keys with this purpose. Instead you can use the methods on + \ref BKeyStore to access keys within keyrings. + + \since Haiku R1 */ /*! - \var BKeyPurpose::B_KEY_PURPOSE_WEB - \brief Undocumented + \var BKeyPurpose::B_KEY_PURPOSE_WEB + \brief Web key purpose - \since Haiku R1 + This type refers to keys that are used on the web, such as username and + passwords for HTTP authentication, as well as for stored usernames and + passwords for form-based authentication. + + \since Haiku R1 */ /*! - \var BKeyPurpose::B_KEY_PURPOSE_NETWORK - \brief Undocumented + \var BKeyPurpose::B_KEY_PURPOSE_NETWORK + \brief Network key purpose - \since Haiku R1 + This type refers to keys that are used in the networking stack, such as + WEP/WPA keys. + + \since Haiku R1 */ /*! - \var BKeyPurpose::B_KEY_PURPOSE_VOLUME - \brief Undocumented + \var BKeyPurpose::B_KEY_PURPOSE_VOLUME + \brief Volume key purpose - \since Haiku R1 + This type refers to keys that are used to lock volumes, like password for + encryption. + + \since Haiku R1 */ @@ -83,42 +108,53 @@ /*! - \enum BKeyType - \brief Undocumented + \enum BKeyType + \brief Descriptive constant for the type of a key. - \since Haiku R1 + \since Haiku R1 */ /*! - \var BKeyType::B_KEY_TYPE_ANY - \brief Undocumented + \var BKeyType::B_KEY_TYPE_ANY + \brief Query the key store for keys of any type - \since Haiku R1 + This constant does not represent a key type by itself, but rather is + used in querying the key store where you do not know or care about the + type of key you are looking for. + + \since Haiku R1 */ /*! - \var BKeyType::B_KEY_TYPE_GENERIC - \brief Undocumented + \var BKeyType::B_KEY_TYPE_GENERIC + \brief Generic key type. - \since Haiku R1 + This constant describes the type of key that does not have any particular + content or format. They are represented by the \ref BKey class. + + \since Haiku R1 */ /*! - \var BKeyType::B_KEY_TYPE_PASSWORD - \brief Undocumented + \var BKeyType::B_KEY_TYPE_PASSWORD + \brief The key is a password. - \since Haiku R1 + This key type is represented by the \ref BPasswordKey class. + + \since Haiku R1 */ /*! - \var BKeyType::B_KEY_TYPE_CERTIFICATE - \brief Undocumented + \var BKeyType::B_KEY_TYPE_CERTIFICATE + \brief The key is a certificate. Not in use. - \since Haiku R1 + This key type is for future expansion. It is currently not in use. + + \since Haiku R1 */ @@ -126,60 +162,101 @@ /*! - \class BKey - \brief Undocumented + \class BKey + \ingroup app + \ingroup libbe + \brief Class that represents a generic key for or from the Haiku key + store - \since Haiku R1 + A key has the following properties: + - A key \b type of \ref BKeyType, which identifies the type. For a generic + key (like this key), it will be set to \ref BKeyType::B_KEY_TYPE_GENERIC. + - A key \b purpose of \ref BKeyPurpose, which identifies the purpose of the + key. This is a hint for your (or other) applications on how and where the + key may be used. + - A \b primary \b identifier that identifies a specific key. As an example, + for WPA passwords, this is set to the network name. This should be a + valid UTF-8 string. + - A \b secondary \b identifier that can be used as additional metadata. + - The \b data, the actual value of the key (such as a password or a + certificate). This should be a valid UTF-8 string. + - Not in use: the \b owner identifies who created and/or owns the key. + This feature is not yet enabled. It will always be set to an empty + string. + - Not in use: the \b creation \b time will indicate when a key was stored + in the central database. This feature is not yet enabled, and the value + will always be 0. + + \since Haiku R1 */ /*! \fn BKey::BKey(); - \brief Undocumented + \brief Constructor for an empty generic key. - \since Haiku R1 + An empty key has no data associated with it, other than that it has a + generic purpose and a generic key type. + + \since Haiku R1 */ /*! \fn BKey::BKey(BKeyPurpose purpose, const char* identifier, - const char* secondaryIdentifier = NULL, const uint8* data = NULL, + const char* secondaryIdentifier = NULL, const uint8* data = NULL, size_t length = 0) - \brief Undocumented + \brief Constructor for a generic key with the provided data. - \since Haiku R1 + See the class introduction for more information about the properties of + a key. As you can see, the only required parameters are the \a purpose + and the \a identifier. Any data you provide will be copied into the BKey + object. + + \param purpose The purpose of this key + \param identifier A unique identifier for this key + \param secondaryIdentifier An (optional) secondary identifier for this key + \param data A pointer to a buffer that contains the value of the key, such + as the password or the certificate data. + \param length The length of the data in bytes that should be copied. + + \since Haiku R1 */ /*! \fn BKey::BKey(BKey& other) - \brief Undocumented + \brief Copy constructor that makes a copy of an \a other BKey. - \since Haiku R1 + \since Haiku R1 */ /*! \fn virtual BKey::~BKey() - \brief Undocumented + \brief Free all resources associated with this key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn virtual BKeyType BKey::Type() const - \brief Undocumented + \brief Returns the type of key. - \since Haiku R1 + For a generic BKey, this will always be \ref BKeyType::B_KEY_TYPE_GENERIC + + \since Haiku R1 */ /*! \fn void BKey::Unset() - \brief Undocumented + \brief Reset the values of the key. - \since Haiku R1 + All properties of the key will be reset, except for the identifying owner. + + \since Haiku R1 */ @@ -187,236 +264,316 @@ \fn status_t BKey::SetTo(BKeyPurpose purpose, const char* identifier, const char* secondaryIdentifier = NULL, const uint8* data = NULL, size_t length = 0) - \brief Undocumented + \brief Set the key to the specified values. - \since Haiku R1 + All properties of the key will be set to the parameters. If the key had a + creation time set, it will be cleared. If there was an owner set, this + piece of information will \em not be cleared. + + \param purpose The purpose of this key + \param identifier A unique identifier for this key + \param secondaryIdentifier An (optional) secondary identifier for this key + \param data A pointer to a buffer that contains the value of the key, such + as the password or the certificate data. + \param length The length of the data in bytes that should be copied. + + \returns + - \c B_OK if the changes were successful. + - \c B_NO_MEMORY in case it fails to allocate memory. + + \since Haiku R1 */ /*! \fn void BKey::SetPurpose(BKeyPurpose purpose) - \brief Undocumented + \brief Set the purpose of the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn BKeyPurpose BKey::Purpose() const - \brief Undocumented + \brief Get the purpose of the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn void BKey::SetIdentifier(const char* identifier) - \brief Undocumented + \brief Set the identifier of the key. - \since Haiku R1 + \param identifier A pointer to a valid UTF-8 string. + + \since Haiku R1 */ /*! \fn const char* BKey::Identifier() const - \brief Undocumented + \brief Get the identifier of the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn void BKey::SetSecondaryIdentifier(const char* identifier) - \brief Undocumented + \brief Set the secondary identifier of the key. - \since Haiku R1 + \param identifier A pointer to a valid UTF-8 string. + + \since Haiku R1 */ /*! \fn const char* BKey::SecondaryIdentifier() const - \brief Undocumented + \brief Get the secondary identifier of the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn status_t BKey::SetData(const uint8* data, size_t length) - \brief Undocumented + \brief Set the data for the key. - \since Haiku R1 + \param data A pointer to the buffer that contains the data of the key. + \param length The length in bytes of the data. + + \returns + - \c B_OK if the key data was updated. + - \c B_NO_MEMORY in case it fails to allocate memory. + \since Haiku R1 */ /*! \fn size_t BKey::DataLength() const - \brief Undocumented + \brief Get the size of the key in bytes. - \since Haiku R1 + \since Haiku R1 */ /*! \fn const uint8* BKey::Data() const - \brief Undocumented + \brief Get a pointer to the data of the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn status_t BKey::GetData(uint8* buffer, size_t bufferSize) const - \brief Undocumented + \brief Copy the key into the \a buffer. - \since Haiku R1 + It is up to you to make sure the size of the buffer is the actual size of + the key's data. If the provided buffer is smaller, only the \a bufferSize + will be copied. If the buffer is larger, the key is copied, but the rest + of the buffer will not be touched. + + \param[out] buffer The buffer to copy the key to. + \param[in] bufferSize The size of the provided \a buffer. + + \returns + - \c B_OK if the data is sucessfully copied. + - An other error code if there was an issue copying the data. + + \since Haiku R1 */ /*! \fn const char* BKey::Owner() const - \brief Undocumented + \brief Get the owner of the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn bigtime_t BKey::CreationTime() const - \brief Undocumented + \brief Get the creation time of the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn virtual status_t BKey::Flatten(BMessage& message) const - \brief Undocumented + \brief Flatten the key into a \a message. - \since Haiku R1 + \since Haiku R1 */ /*! \fn virtual status_t BKey::Unflatten(const BMessage& message) - \brief Undocumented + \brief Unflatten the key from a \a message. - \since Haiku R1 + \since Haiku R1 */ /*! \fn BKey& BKey::operator=(const BKey& other) - \brief Undocumented + \brief Copy the data from the \a other key into this key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn bool BKey::operator==(const BKey& other) const - \brief Undocumented + \brief Compare this key to an \a other key. - \since Haiku R1 + \returns \c true if all the properties in both keys are identical. + + \since Haiku R1 */ /*! \fn bool BKey::operator!=(const BKey& other) const - \brief Undocumented + \brief Compare this key to an \a other key. - \since Haiku R1 + \returns \c true if any of the properties in this key differ from \a other. + + \since Haiku R1 */ /*! - \fn virtual void BKey::PrintToStream(); - \brief Undocumented + \fn virtual void BKey::PrintToStream() + \brief Dump the contents of the key to standard output. - \since Haiku R1 + This is a debug function that helps you read the contents of the key. All + properties, except for the actual \c data of the key, will be printed to + \c stdout. + + \since Haiku R1 */ ///// BPasswordKey class ///// - /*! - \class BPasswordKey - \brief Undocumented + \class BPasswordKey + \ingroup app + \ingroup libbe + \brief Class that represents a password for or from the Haiku key store. - \since Haiku R1 + This is a specialized version of the BKey class, which represents a key of + the \ref BKeyType::B_KEY_TYPE_PASSWORD. + + \since Haiku R1 */ /*! \fn BPasswordKey::BPasswordKey() - \brief Undocumented + \brief Constructor for an empty password key. - \since Haiku R1 + An empty key has no data associated with it, other than that it has a + generic purpose and a password key type. + + \since Haiku R1 */ /*! \fn BPasswordKey::BPasswordKey(const char* password, BKeyPurpose purpose, - const char* identifier, const char* secondaryIdentifier = NULL) - \brief Undocumented + const char* identifier, const char* secondaryIdentifier = NULL) + \brief Constructor for a password key with the provided data. - \since Haiku R1 + See the BKey introduction for more information about the properties of + a key. As you can see, the only required parameters are the \a purpose + and the \a identifier. Any data you provide will be copied into the BKey + object. + + \param password A null-terminated string that contains the password + \param purpose The purpose of this key + \param identifier A unique identifier for this key + \param secondaryIdentifier An (optional) secondary identifier for this key + + \since Haiku R1 */ /*! \fn BPasswordKey::BPasswordKey(BPasswordKey& other) - \brief Undocumented + \brief Copy constructor that makes a copy of an \a other BPasswordKey. - \since Haiku R1 + \since Haiku R1 */ /*! \fn virtual BPasswordKey::~BPasswordKey() - \brief Undocumented + \brief Free all resources associated with this key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn virtual BKeyType BPasswordKey::Type() const - \brief Undocumented + \brief Returns \ref BKeyType::B_KEY_TYPE_PASSWORD. - \since Haiku R1 + \since Haiku R1 */ /*! \fn status_t BPasswordKey::SetTo(const char* password, BKeyPurpose purpose, const char* identifier, const char* secondaryIdentifier = NULL) - \brief Undocumented + \brief Set the key to specific values. - \since Haiku R1 + All properties of the key will be set to the parameters. If the key had a + creation time set, it will be cleared. If there was an owner set, this + piece of information will \em not be cleared. + + \param password A null-terminated string that contains the password + \param purpose The purpose of this key + \param identifier A unique identifier for this key + \param secondaryIdentifier An (optional) secondary identifier for this key + + \returns + - \c B_OK if the changes were successful. + - \c B_NO_MEMORY in case it fails to allocate memory. + + \since Haiku R1 */ /*! \fn status_t BPasswordKey::SetPassword(const char* password) - \brief Undocumented + \brief Set the \a password for this key. - \since Haiku R1 + \param password A null-terminated string that contains the password. + + \since Haiku R1 */ /*! \fn const char* BPasswordKey::Password() const - \brief Undocumented + \brief Get the password for the key. - \since Haiku R1 + \since Haiku R1 */ /*! \fn virtual void BPasswordKey::PrintToStream() - \brief Undocumented + \brief Dump the contents of the key to standard output. - \since Haiku R1 + This is a debug function that helps you read the contents of the key. All + properties, including the actual \b password, will be printed to \c stdout. + + \since Haiku R1 */ diff --git a/docs/user/app/KeyStore.dox b/docs/user/app/KeyStore.dox index 288d3f5075..b2917a3f9e 100644 --- a/docs/user/app/KeyStore.dox +++ b/docs/user/app/KeyStore.dox @@ -1,5 +1,5 @@ /* - * Copyright 2019 Haiku, Inc. All rights reserved. + * Copyright 2020 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -16,6 +16,9 @@ \ingroup app \ingroup libbe \brief Provides BKeyStore class. + + See the \link app_keystore overview to the Password and Key Storage API + \endlink for an introduction to the API. */ @@ -23,25 +26,52 @@ \class BKeyStore \ingroup app \ingroup libbe - \brief Undocumented + \brief The BKeyStore lets you query, retrieve and store keys in the + system's key store. - \since Haiku R1 + Instances of this object give you an easy API to interact with the system's + \c keystore_server. This is the central service that manages storing and + retrieving keys, as well as managing the authorizations that a user grants + to individual applications. + + It is important to note that all calls on this object operate + \b synchronously. This means that it should not be used during the event + loop of a visible \ref BWindow, as this may cause drawing and interaction + issues. + + All operations are performed in the context of a keyring. All systems have + at least the \b Master \b keyring. Many of the methods take the name of the + keyring as its first argument. Most of the methods in this class have an + overloaded variant that operate on the Master keyring. If you want to + access this keyring through the normal methods, pass an empty string as the + identifier to the method. + + See the \link app_keystore overview to the Password and Key Storage API + \endlink for an introduction to the API. + + + \since Haiku R1 */ /*! - \fn BKeyStore::BKeyStore() - \brief undocumented + \fn BKeyStore::BKeyStore() + \brief Create a new BKeyStore object that you can use to query, retrieve + and store keys in the system's key store. - \since Haiku R1 + This is a cheap object to make, as it has no data associated with it. The + recommended use is to create an instance on the stack whenever you want to + interact with the API. + + \since Haiku R1 */ /*! - \fn virtual BKeyStore::~BKeyStore() - \brief undocumented + \fn virtual BKeyStore::~BKeyStore() + \brief Free all resources. - \since Haiku R1 + \since Haiku R1 */ /*! @@ -53,20 +83,30 @@ /*! - \fn status_t BKeyStore::GetKey(BKeyType type, const char* identifier, + \fn status_t BKeyStore::GetKey(BKeyType type, const char* identifier, BKey& key) - \brief Undocumented + \brief Query the Master keyring for for specific key. - \since Haiku R1 + This is a convenience method that calls \ref GetKey(const char* keyring, BKeyType type, const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key). + + It works on the Master \a keyring, and assumes an empty + \a secondaryIdentifier, \a secondaryIdentifierOptional set to \c false. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetKey(BKeyType type, const char* identifier, const char* secondaryIdentifier, BKey& key) - \brief Undocumented + \brief Query the Master keyring for for specific key. - \since Haiku R1 + This is a convenience method that calls \ref GetKey(const char* keyring, BKeyType type, const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key). + + It works on the Master \a keyring, it sets \a secondaryIdentifierOptional + to \c false, meaning it both identifiers are required to match. + + \since Haiku R1 */ @@ -74,104 +114,232 @@ \fn status_t BKeyStore::GetKey(BKeyType type, const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key) - \brief Undocumented + \brief Query the Master keyring for for specific key. - \since Haiku R1 + This is a convenience method that calls \ref GetKey(const char* keyring, BKeyType type, const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key). + + It works on the Master \a keyring. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetKey(const char* keyring, BKeyType type, - const char* identifier, BKey& key) - \brief Undocumented + const char* identifier, BKey& key) + \brief Query a certain \a keyring for for specific key. - \since Haiku R1 + This is a convenience method that calls \ref GetKey(const char* keyring, BKeyType type, const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key). + + The call assumes an empty \a secondaryIdentifier, and sets + \a secondaryIdentifierOptional to \c false. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetKey(const char* keyring, BKeyType type, - const char* identifier, const char* secondaryIdentifier, BKey& key) - \brief Undocumented + const char* identifier, const char* secondaryIdentifier, BKey& key) + \brief Query a certain \a keyring for for specific key. - \since Haiku R1 + This is a convenience method that calls \ref GetKey(const char* keyring, BKeyType type, const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key). + + It sets \a secondaryIdentifierOptional to \c false, meaning it both + identifiers are required to match. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetKey(const char* keyring, BKeyType type, - const char* identifier, const char* secondaryIdentifier, + const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key) - \brief Undocumented + \brief Query a certain \a keyring for for specific key. - \since Haiku R1 + This variation of the query function is useful when you know that a key has + a secondary identifier, but you may not know it, or care about what it is. + + \param[in] keyring A string that identifies the keyring get the key from. + \param[in] type The type of key to match. The type parameter is currently + ignored and therefore does not need to match the actual type of the key + that is stored. + \param[in] identifier The string with the primary identifier of the key that + you are looking for. + \param[in] secondaryIdentifier The string with the secondary identifier of + the key that you are looking for. + \param[in] secondaryIdentifierOptional Use this query parameter to indicate + if the secondary identifier has to match. When set to \a false, a + result will be returned, even if the \a secondaryIdentifer does not + match. + \param[out] key A BKey object to copy the found data to. Any existing data + in the key will be overwritten in case there is a match. + + \returns + - \c B_OK in case the key was found and stored in \a key. + - \c B_BAD_VALUE in case the \a keyring does not exist. + - \c B_NOT_ALLOWED in case the user did not grant you access right to + this \a keyring. + - \c B_ENTRY_NOT_FOUND in case there is no key that matches the given + identifier(s). + - Any other error that indicates that there was a problem communicating + with the \c keystore_server. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::AddKey(const BKey& key) - \brief Undocumented + \brief Add a \a key to the Master keyring - \since Haiku R1 + This is a convenience method that calls + \ref AddKey(const char *, const BKey&) for the \c Master keyring. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::AddKey(const char* keyring, const BKey& key) - \brief Undocumented + \brief Add a \a key to a \a keyring. - \since Haiku R1 + This method will send the key to the \c keystore_server and request it to + be stored in the database. + + A key needs to have a unique primary and secondary identifier within the + Master keyring. + + \param keyring A string that identifies the keyring you want to add the + key to. + \param key The key you want to add. + + \returns + - \c B_OK in case the \a key was succesfully added. + - \c B_BAD_VALUE in case the \a keyring does not exist. + - \c B_NOT_ALLOWED in case the user did not grant you access right to + this \a keyring. + - \c B_NAME_IN_USE in case there already is another key with the same + primary and secondary identifiers. + - Any other error that indicates that there was a problem communicating + with the \c keystore_server. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::RemoveKey(const BKey& key) - \brief Undocumented + \brief Remove a \a key from the Master keyring. - \since Haiku R1 + This is a convenience method that calls + \ref RemoveKey(const char *, const BKey&) for the \c Master keyring. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::RemoveKey(const char* keyring, const BKey& key) - \brief Undocumented + \brief Remove a \a key from a \a keyring. - \since Haiku R1 + This method will remove a \a key from a \a keyring. The \a key needs to + match exactly with the key that is in the database of \c keystore_server. + The easiest way to guarantee this, is to use the exact key you find using + GetKey() without making any alterations. + + \param keyring A string that identifies the keyring you want to remove + the key from. + \param key The key you want to remove. + + \returns + - \c B_OK in case the \a key was succesfully removed. + - \c B_BAD_VALUE in case the \a keyring does not exist. + - \c B_NOT_ALLOWED in case the user did not grant you access right to + this \a keyring. + - \c B_ENTRY_NOT_FOUND in case there is no key that matches the given + identifier(s). + - Any other error that indicates that there was a problem communicating + with the \c keystore_server. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetNextKey(uint32& cookie, BKey& key); - \brief Undocumented + \brief Iterate through the keys of the Master keyring. - \since Haiku R1 + This convenience method that calls + \ref GetNextKey(const char*, BKeyType, BKeyPurpose, uint32&, BKey&) for the + Master keyring, with the arguments \ref BKeyType::B_KEY_TYPE_ANY for the + type and \ref BKeyPurpose::B_KEY_PURPOSE_ANY for the purpose. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetNextKey(BKeyType type, BKeyPurpose purpose, uint32& cookie, BKey& key) - \brief Undocumented + \brief Iterate through the keys of the Master keyring. - \since Haiku R1 + This convenience method calls + \ref GetNextKey(const char*, BKeyType, BKeyPurpose, uint32&, BKey&) for the + Master keyring. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetNextKey(const char* keyring, uint32& cookie, - BKey& key) - \brief Undocumented + BKey& key) + \brief Iterate through the keys of a \a keyring. - \since Haiku R1 + This convenience method calls + \ref GetNextKey(const char*, BKeyType, BKeyPurpose, uint32&, BKey&) with + the arguments \ref BKeyType::B_KEY_TYPE_ANY for the type and + \ref BKeyPurpose::B_KEY_PURPOSE_ANY for the purpose. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetNextKey(const char* keyring, BKeyType type, - BKeyPurpose purpose, uint32& cookie, BKey& key) - \brief Undocumented + BKeyPurpose purpose, uint32& cookie, BKey& key) + \brief Iterate through keys of a \a keyring. - \since Haiku R1 + This method allows you to query through the key store, and iterate through + a list of results of keys that match your query. + + \param[in] keyring An UTF-8 string that identifies the keyring + \param[in] type The BKeyType that identifies the type of key you are + looking for. This may be \ref BKeyType::B_KEY_TYPE_ANY if it may be a + key of any type. + \param[in] purpose The BKeyPurpose that indicates the purpose of the key. + This may be \ref BKeyPurpose::B_KEY_PURPOSE_ANY if it may be a key with + any purpose. + \param[out] cookie A cookie that the \c keystore_server uses to keep track + of where you are in the list of keys. When you start the query, set the + initial value to \c 0. After that, pass the cookie to each subsequent + call to progress the iterator. + \param[out] key The key that holds the data. Any existing data in the key + will be overwritten, when a key is found that matches the criteria. + + \returns + - \c B_OK in case the next \a key was found. + - \c B_BAD_VALUE in case the \a keyring does not exist. + - \c B_NOT_ALLOWED in case the user did not grant you access right to + this \a keyring. + - \c B_ENTRY_NOT_FOUND in case there is no key that matches the given + identifier(s), or if you retrieved the last key. + - Any other error that indicates that there was a problem communicating + with the \c keystore_server. + + \since Haiku R1 */ @@ -188,41 +356,73 @@ /*! \fn status_t BKeyStore::AddKeyring(const char* keyring) - \brief Undocumented + \brief Create a new \a keyring. - \since Haiku R1 + \param keyring An UTF-8 string that identifies the keyring you want to + create. + + \returns + - \c B_OK if the keyring was succesfully added. + - \c B_NAME_IN_USE if the \a keyring already exists. + - Any other error in case there was an unknown error in the + \c keystore_server, or while communicating to it. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::RemoveKeyring(const char* keyring) - \brief Undocumented + \brief Remove a \a keyring. - \since Haiku R1 + \param keyring An UTF-8 string that identifies the keyring you want to + remove. + + \returns + - \c B_OK if the keyring was sucessfully removed. + - \c B_ENTRY_NOT_FOUND if the keyring does not exist + - \c B_NOT_ALLOWED when you try to remove the Master keyring. + - Any other error in case there was an unknown error in the + \c keystore_server, or while communicating to it. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetNextKeyring(uint32& cookie, BString& keyring) - \brief Undocumented + \brief Iterate through the keyrings. - \since Haiku R1 + \param[out] cookie A cookie that the \c keystore_server uses to keep track + of where you are in the list of keyrings. When you start the query, set + the initial value to \c 0. After that, pass the cookie to each + subsequent call to progress the iterator. + \param[out] keyring A BString that holds the current name of the keyring. + For each succesful iteration, the existing contents is overwritten. + + \returns + - \c B_OK if the iteration was succesful. + - \c B_ENTRY_NOT_FOUND if there are no more keyrings left to iterate + - Any other error in case there was an unknown error in the + \c keystore_server, or while communicating to it. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::SetUnlockKey(const char* keyring, const BKey& key) - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. */ /*! \fn status_t BKeyStore::RemoveUnlockKey(const char* keyring) - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. */ @@ -230,7 +430,7 @@ /*! - \name Master keyring + \name Master keyring (future API) */ @@ -239,42 +439,48 @@ /*! \fn status_t BKeyStore::SetMasterUnlockKey(const BKey& key) - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. */ /*! \fn status_t BKeyStore::RemoveMasterUnlockKey() - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. */ /*! \fn status_t BKeyStore::AddKeyringToMaster(const char* keyring) - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. + + \see AddKeyring(const char* keyring) */ /*! \fn status_t BKeyStore::RemoveKeyringFromMaster(const char* keyring) - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. + + \see RemoveKeyring(const char* keyring) */ /*! \fn status_t BKeyStore::GetNextMasterKeyring(uint32& cookie, - BString& keyring) - \brief Undocumented + BString& keyring) + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. + + \see GetNextKeyring(uint32& cookie, BString& keyring) */ @@ -282,7 +488,16 @@ /*! - \name Locking + \name Locking (future API) + + In the future, locking is part of encrypting and decrypting keyrings. + + \note If you are looking at this section because you assume you need to + check that users have the correct permissions, you are in the wrong + place. There is no particular way to determine whether a user has + access granted. Instead, each method of this API will return the error + code \c B_NOT_ALLOWED if the user has not granted access. Use that in + your control flow to determine if you have access. */ @@ -291,25 +506,25 @@ /*! \fn bool BKeyStore::IsKeyringUnlocked(const char* keyring) - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. */ /*! \fn status_t BKeyStore::LockKeyring(const char* keyring) - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. */ /*! \fn status_t BKeyStore::LockMasterKeyring() - \brief Undocumented + \brief Not implemented. - \since Haiku R1 + This feature is not available in the current release of Haiku. */ @@ -327,35 +542,82 @@ /*! \fn status_t BKeyStore::GetNextApplication(uint32& cookie, BString& signature) const - \brief Undocumented + \brief Iterate through applications that currently have been granted access + to the Master keyring. - \since Haiku R1 + This is a convenience method that calls + \ref GetNextApplication(const char* keyring, uint32& cookie, + BString& signature) for the Master \a keyring. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::GetNextApplication(const char* keyring, uint32& cookie, BString& signature) const - \brief Undocumented + \brief Iterate through applications that currently have been granted access + to the specified \a keyring. - \since Haiku R1 + This method allows you to iterate through all applications that the user + has granted access to the \a keyring, whether it is temporarily, or on a + more permanent basis. + + \param[in] keyring A UTF-8 string that identifies the keyring that you want + to inspect granted access to. + \param[out] cookie A cookie that the \c keystore_server uses to keep track + of where you are in the list of keys. When you start the query, set the + initial value to \c 0. After that, pass the cookie to each subsequent + call to progress the iterator. + \param[out] signature If a next application is found, the signature will be + stored in this parameter. Any existing string will be overwritten. + + \returns + - \c B_OK if the next signature was found succesfully. + - \c B_BAD_VALUE if the keyring does not exist. + - \c B_NOT_ALLOWED in case the user did not grant you access right to + this \a keyring. + - \c B_ENTRY_NOT_FOUND if there are no more applications to iterate + through. + - Any other error in case there was an unknown error in the + \c keystore_server, or while communicating to it. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::RemoveApplication(const char* signature) - \brief Undocumented + \brief Remove access for an application to the Master keyring. - \since Haiku R1 + This is a convenience method that calls + \ref RemoveApplication(const char *, const char*) for the Master + \a keyring. + + \since Haiku R1 */ /*! \fn status_t BKeyStore::RemoveApplication(const char* keyring, const char* signature) - \brief Undocumented + \brief Remove access for an application to a \a keyring. - \since Haiku R1 + \param keyring A UTF-8 string that identifies the keyring that you want + to inspect granted access to. + \param signature The signature of the application that you want to revoke + permissions to access the keyring. + + \returns + - \c B_OK if the application's access has been revoked. + - \c B_NOT_ALLOWED in case the user did not grant you access right to + this \a keyring. + - \c B_ENTRY_NOT_FOUND if the application did not have access to this + keyring. + - Any other error in case there was an unknown error in the + \c keystore_server, or while communicating to it. + + \since Haiku R1 */ @@ -363,7 +625,9 @@ /*! - \name Service Functions + \name Service Functions (future API) + + This feature is not available in the current release of Haiku. */ @@ -373,17 +637,17 @@ /*! \fn status_t BKeyStore::GeneratePassword(BPasswordKey& password, size_t length, uint32 flags) - \brief Undocumented + \brief Unimplemented. - \since Haiku R1 + This method is currently not implemented. */ /*! \fn float BKeyStore::PasswordStrength(const char* password) - \brief Undocumented + \brief Unimplemented - \since Haiku R1 + This method is currently not implemented */ diff --git a/docs/user/app/_app_keystore.dox b/docs/user/app/_app_keystore.dox new file mode 100644 index 0000000000..e6a2a7db3b --- /dev/null +++ b/docs/user/app/_app_keystore.dox @@ -0,0 +1,231 @@ +/* + * Copyright 2020 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Niels Sascha Reedijk, niels.reedijk@gmail.com + */ + +/*! + \page app_keystore Password and Key Storage API + + Haiku R1 introduces the first version of a system-wide key store service, + allows you as developer to outsource some of the credential and certificate + management, as well as providing an infrastructure that enables sharing + these artifacts between applications. + + \warning The implementation in Haiku R1 is limited and is a promise of more + to come. Functionality beyond storing and sharing passwords is for the + future. Also please read the security section of this document, + especially when you are working with artifacts that are more sensitive. + In many cases you will find that this system service will work just as + well as making your own implementation, but there are instances in + which you may chose not to use it. + + \section app_keystore_overview 1. Highlevel Overview (components) + + The implementation is based around the following concepts: + - The \b keystore is the centralized repository for your keys. It is + managed by the \b keystore_server and it contains one or more + \b keyrings. + - A \b keyring is a collection of keys. There is always a + \b master \b keyring, which cannot be removed. Access is organized + around keyrings. From a user's perspective, when an application wants + to access keys in a keyring, the user will have to grant permission to + that application to access the keyring. A keyring is identified by a + name, which needs to be unique on the user's system. + - A keyring contains \b keys. These are the smallest unit in the system. + A key can be anything that you want to safeguard in the keystore. Keys + are identified by the combination of an identifier and a secondary + identifier. These should be unique within a keyring. + - The final piece is the concept of \b permissions. In the current + implementation, an application needs to ask permission to access a + keyring. The \c keystore_server will validate the permissions, and if + necessary prompt the user to grant one-time or a permant access. If the + user only allows it once, access is granted until the application + terminates. + + As a user of the API, you will mostly be working with \ref BKeyStore, as + the access point that queries and modifies keyrings and keys. An individual + key is represented by the \ref BKey object. + + \section app_keystore_security 2. Security + + The current implementation of this API should be considered low-security. + The most important thing to know is that there is \b no \b encryption + applied when storing the keys and keyrings to the drive. This means that + the data can be read by any malicious actor that can access the drive of + your machine. + + This should also puts the current locking mechanism in perspective. While + the \c keystore_server will prompt the user to grant (or deny) access to + your application, when it wants to access a keyring, this again does not + prevent any malicious actor to bypass the \c keystore_server and directly + read from (and write to!) the file. + + When considering on whether to use the current API, there are a few things + to think about: + - First, consider whether you should store the keys at all. Passwords to + services with extremely sensitive personal or financial information, + such as email passwords or credentials to financial institutions, should + not be stored at all. Prompt your user for the credentials when needed, + and don't keep them for later use. + - Secondly, if you are storing credentials for use with web services, + check if the service you are using supports using access tokens. Many + APIs have them, and often use it in combination with some form of + permission system or scoping, making it possible for you to keep access + as limited as possible. Furthermore, the user often has the ability to + revoke access to a token, in case they think it is compromised. + - When you assess that you really do need to store the credentials, make + a determination first about whether or not the credentials should have + some form of encryption. For now you should consider looking for another + solution to storing sensitive data, but contributions to improve this + API are very welcome. It is beyond the scope of this document to discuss + strategies around encryption. + - When you assess the risk is low enough not to employ encryption + strategies, you may consider using this API. It is particularly + recommended if you will be sharing the credentials with more than one + application. + + \warning In the end, it is up to you as a developer to be conscious of any + choices you make when it comes to user data, and credentials are no + different. When you decide that the Password and Key API does not fit + your needs, choose a framework or library that does fit your purpose. + + \section app_keystore_usage 3. Practical use of the API + + Below are two distinct examples on how you may use the API. + + \subsection app_keystore_usage_web The Langlaufer Web Browser + + We are working on the infamous Langlaufer web browser, and we are adding + a feature where we autocomplete user names and passwords. It is decided to + use the Password and Key Storage API to do our key management. Whenever we + land on a web page with a login screen, we will try to see if we have + credentials for that web page. Part of the requirements is that we support + more than one set of credentials for a web page. + + It is decided that the application will store the user credentials in it's + own keyring, as we do not want to interfere with any other keys in the + master key. Additionally, we will use both the primary and secondary + identifier fields. The primary will contain the hostname of the website, + and the secondary will contain the user name. + + One final design note is that all the calls to the \c keystore_server are + synchronous, meaning they will block until there is a response back from + the keystore. In the case that a user needs to be prompted for a password, + the call will be blocked until they make a decision. That is why any calls + on \ref BKeyStore should be done on a separate worker thread, instead of + within the logic of a Window. + + For clarity, the example below displays the interaction with the + \ref BKeyStore and \ref BKey classes through some utility functions. It is + up to the reader to put that in a separate working thread. + + \code{.cpp} + #include + #include + + const char *kLanglauferKeyringName = "Langlaufer"; + + BObjectList + GetKeysForWebsite(const char *baseUrl) { + // There may be more than one match, so we use the iteration methods. + BKeyStore keyStore; + uint32 cookie; + BPasswordKey currentKey; + BObjectList list; + bool next = true; + + while(next) { + status_t status = keyStore.GetNextKey(kLanglauferKeyringName, + B_KEY_TYPE_PASSWORD, B_KEY_PURPOSE_WEB, cookie, currentKey); + switch(status) { + case B_OK: + // Try to see if the key matches the website + if (currentKey.Identifier() == baseUrl) { + // Add the item to the list. + list.AddItem(new BPasswordKey(currentKey)); + } + break; + case B_BAD_VALUE: + // The keyring does not exist, create it, and end the + // search + CreateKeyring(); + next = false; + break; + default: + // Something else went wrong, like the user did not give + // authorization, or we are at the end of the list. + // Bail out the search at this point. + next = false; + break; + } + } + } + + return list; + } + + void + CreateKeyring() { + BKeyStore keyStore; + // Ignore the return value in the next line, it may fail but that won't + // interrupt the flow of our program. + keyStore.AddKeyring(kLanglauferKeyringName); + } + + void + AddOrReplaceKey(const char *baseUrl, const char *user, const char *password) { + BKeyStore keyStore; + BPasswordKey key; + + // Fill out the key with existing data, or create new data + if (keyStore.GetKey(kLanglauferKeyringName, B_KEY_TYPE_PASSWORD, baseUrl, user, &key) == B_OK) { + // Remove the existing key + keyStore.RemoveKey(kLanglauferKeyringName, key); + // Update the password + key.SetPassword(password); + } else { + key.SetTo(password, B_KEY_PURPOSE_WEB, user, password); + } + + // Store the updated/new key in the keyring + keyStore.AddKey(kLanglauferKeyringName, key); + } + \endcode + + \subsection app_keystore_usage_coolwebservice The CoolWebService Tool Suite + + We are working on a set of tools that interface with a cool web service. + Instead of building one monolithic application, we make several small tools + with specific jobs for this cool web service. One of the tools does the + authentication, and stores the key in the master keyring on the system. The + other tools use this key to access the API. + + Each tool requires the authentication token to be set up properly. That's + why in the \ref BApplication::ReadyToRun() hook we check for the + availability of the key. If it is not available, or it does not work, the + user will be redirected to the authentication tool. The key will be stored + as a password. It will be identified by the identifer "CoolWebService". + + \code{.cpp} + void + CoolPushTool::ReadyToRun() { + BKeyStore keyStore; + BPasswordKey key; + + if (keyStore.GetKey(B_KEY_TYPE_PASSWORD, "CoolWebService", key) != B_OK) { + // Terminate the application and re-authenticate + ... + } + + // Extract the key + BString accessToken = key.Password(); + + // Validate the key, and if succesful, continue + ... + } + \endcode + +*/ diff --git a/docs/user/book.dox b/docs/user/book.dox index 188f46616c..7107a559c3 100644 --- a/docs/user/book.dox +++ b/docs/user/book.dox @@ -102,9 +102,16 @@ - BApplication - BClipboard - BCursor + - BLaunchRoster + - BNotification - BPropertyInfo - BRoster + A third special category is the \link app_keystore Password and Key storage + API:\endlink + - BKey + - BKeyStore + \defgroup game Game Kit \brief The Game Kit provides classes for producing game sounds and